local extension = Package("joy_god")
extension.extensionName = "joy"

Fk:loadTranslationTable{
  ["joy_god"] = "欢乐-神",
}

-- 神武将，包括原神武将基础上的修改，以及原创神武将，不包含限时地主

local U = require "packages/utility/utility"


local godsimayi = General(extension, "joy__godsimayi", "god", 3)
local joy__renjie = fk.CreateTriggerSkill{
  name = "joy__renjie",
  anim_type = "special",
  frequency = Skill.Compulsory,
  events = {fk.Damaged, fk.AfterCardsMove, fk.GameStart},
  can_trigger = function(self, event, target, player, data)
    if player:hasSkill(self) then
      if event == fk.Damaged then
        return target == player
      elseif event == fk.AfterCardsMove then
        if player.phase == Player.Discard then
          for _, move in ipairs(data) do
            if move.from == player.id and move.moveReason == fk.ReasonDiscard then
              for _, info in ipairs(move.moveInfo) do
                if info.fromArea == Card.PlayerHand then
                  return true
                end
              end
            end
          end
        end
      else
        return true
      end
    end
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    local n = 0
    if event == fk.Damaged then
      room:addPlayerMark(player, "@godsimayi_bear", data.damage)
    elseif event == fk.AfterCardsMove then
      for _, move in ipairs(data) do
        if move.from == player.id and move.moveReason == fk.ReasonDiscard then
          for _, info in ipairs(move.moveInfo) do
            if info.fromArea == Card.PlayerHand then
              n = n + 1
            end
          end
        end
      end
    else
      n = 1
    end
    room:addPlayerMark(player, "@godsimayi_bear", n)
  end,
}
local joy__jilue = fk.CreateTriggerSkill{
  name = "joy__jilue",
  events = {fk.AskForRetrial, fk.Damaged, fk.CardUsing, fk.EnterDying, fk.AfterSkillEffect},
  can_trigger = function(self, event, target, player, data)
    if event == fk.AfterSkillEffect then
      return data == self and target == player and player:usedSkillTimes("joy__jilue", Player.HistoryTurn) == 1 and not player.dead
    elseif player:hasSkill(self) and player:getMark("@godsimayi_bear") > 0 then
      if event == fk.AskForRetrial then
        return not player:isNude()
      elseif event == fk.Damaged then
        return target == player
      elseif event == fk.CardUsing then
        return target == player and data.card:isCommonTrick()
      elseif event == fk.EnterDying then
        return player == player.room.current and not player:hasSkill("joy__wansha", true)
      end
    end
  end,
  on_cost = function(self, event, target, player, data)
    local room = player.room
    if event == fk.AskForRetrial then
      local card = room:askForResponse(player, "ex__guicai", ".|.|.|hand,equip", "#joy__jilue-guicai::" .. target.id..":"..data.reason, true)
      if card ~= nil then
        self.cost_data = card
        return true
      end
    elseif event == fk.Damaged then
      local to = room:askForChoosePlayers(player, table.map(room:getOtherPlayers(player), Util.IdMapper), 1, 1, "#joy__jilue-fangzhu", "joy__fangzhu", true)
      if #to > 0 then
        self.cost_data = to[1]
        return true
      end
    else
      local list = { [fk.CardUsing] = "jizhi", [fk.EnterDying] = "wansha", [fk.AfterSkillEffect] = "draw", }
      return room:askForSkillInvoke(player, self.name, nil, "#joy__jilue-"..list[event])
    end
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    room:notifySkillInvoked(player, "jilue", (event == fk.CardUsing or event == fk.AfterSkillEffect) and "drawcard" or "control")
    if event == fk.AskForRetrial then
      room:removePlayerMark(player, "@godsimayi_bear", 1)
      player:broadcastSkillInvoke("guicai")
      room:retrial(self.cost_data, player, data, "uicai")
    elseif event == fk.Damaged then
      room:removePlayerMark(player, "@godsimayi_bear", 1)
      player:broadcastSkillInvoke("fangzhu")
      local to = player.room:getPlayerById(self.cost_data)
      to:drawCards(1, "joy__fangzhu")
      if not to.dead then
        to:turnOver()
      end
    elseif event == fk.CardUsing then
      room:removePlayerMark(player, "@godsimayi_bear", 1)
      player:broadcastSkillInvoke("jizhi")
      player:drawCards(1, "jizhi")
    elseif event == fk.EnterDying then
      room:removePlayerMark(player, "@godsimayi_bear", 1)
      data.extra_data = data.extra_data or {}
      data.extra_data.joy__jilue_wansha = player.id
      room:handleAddLoseSkills(player, "joy__wansha")
    else
      player:drawCards(1, "joy__jilue")
    end
  end,
}
local joy__jilue_delay = fk.CreateTriggerSkill{
  name = "#joy__jilue_delay",
  mute = true,
  events = {fk.AfterDying},
  can_trigger = function(self, event, target, player, data)
    return data.extra_data and data.extra_data.joy__jilue_wansha == player.id
  end,
  on_cost = Util.TrueFunc,
  on_use = function(self, event, target, player, data)
    local room = player.room
    room:handleAddLoseSkills(player, "-joy__wansha")
  end,
}
joy__jilue:addRelatedSkill(joy__jilue_delay)
local lianpo = fk.CreateTriggerSkill{
  name = "joy__lianpo",
  anim_type = "offensive",
  events = {fk.TurnEnd},
  can_trigger = function(self, event, target, player, data)
    if player:hasSkill(self) then
      local room = player.room
      local events = room.logic:getEventsOfScope(GameEvent.Death, 999, function(e)
        local deathStruct = e.data[1]
        return deathStruct.damage and deathStruct.damage.from and deathStruct.damage.from == player
      end, Player.HistoryTurn)
      return #events > 0
    end
  end,
  on_cost = function(self, event, target, player, data)
    return player.room:askForSkillInvoke(player, self.name, nil, "#lianpo-invoke")
  end,
  on_use = function(self, event, target, player, data)
    player:gainAnExtraTurn(true)
  end,
}
godsimayi:addRelatedSkill("joy__wansha")

godsimayi:addSkill(joy__renjie)
godsimayi:addSkill(lianpo)
godsimayi:addSkill(joy__jilue)
godsimayi:addRelatedSkill("ex__guicai")
godsimayi:addRelatedSkill("joy__fangzhu")
godsimayi:addRelatedSkill("jizhi")
godsimayi:addRelatedSkill("joy__wansha")
Fk:loadTranslationTable{
  ["joy__godsimayi"] = "神司马懿",
  ["#joy__godsimayi"] = "晋国之祖",
  ["joy__renjie"] = "忍戒",
  [":joy__renjie"] = "锁定技，游戏开始时，你获得1枚“忍”标记；当你受到伤害后/于弃牌阶段弃置手牌后，你获得X枚“忍”（X为伤害值/你弃置的手牌数）。",
  ["joy__jilue"] = "极略",
  [":joy__jilue"] = "你可以弃置1枚“忍”，发动下列一项技能：〖鬼才〗、〖放逐〗、〖集智〗、〖完杀〗；你每回合首次发动〖极略〗时可摸一张牌。",
  ["joy__lianpo"] = "连破",
  [":joy__lianpo"] = "当你杀死一名角色后，你可于此回合结束后获得一个额外的回合。",
  ["#joy__jilue-jizhi"] = "极略：可弃1枚“忍”标记，发动〖集智〗：摸一张牌",
  ["#joy__jilue-wansha"] = "极略：你可以弃1枚“忍”标记，获得〖完杀〗直到濒死结算结束",
  ["#joy__jilue-fangzhu"] = "极略：可弃1枚“忍”标记，发动〖放逐〗：令一名其他角色翻面并摸一张牌",
  ["#joy__jilue-guicai"] = "极略：可弃1枚“忍”标记，发动〖鬼才〗：修改 %dest 的“%arg”判定",
  ["#joy__jilue-draw"] = "极略：你可以摸一张牌",
  ["#joy__jilue_delay"] = "极略",

}

local joy__godliubei = General(extension, "joy__godliubei", "god", 6)
local joy__longnu = fk.CreateTriggerSkill{
  name = "joy__longnu",
  events = {fk.EventPhaseStart},
  anim_type = "offensive",
  frequency = Skill.Compulsory,
  can_trigger = function(self, event, target, player, data)
    return target == player and player:hasSkill(self) and player.phase == Player.Play
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    local choice = room:askForChoice(player, {"joy__longnu_red", "joy__longnu_black"}, self.name)
    local mark = player:getTableMark( "@joy__longnu-turn")
    local color = string.sub(choice, 13, -1)
    table.insertIfNeed(mark, color)
    room:setPlayerMark(player, "@joy__longnu-turn", mark)
    for _, id in ipairs(player:getCardIds("h")) do
      Fk:filterCard(id, player)
    end
    if color == "red" then
      room:loseHp(player, 1, self.name)
      if player.dead then return end
      player:drawCards(2, self.name)
    else
      room:changeMaxHp(player, -1)
    end
  end,
}
local joy__longnu_filter = fk.CreateFilterSkill{
  name = "#joy__longnu_filter",
  card_filter = function(self, card, player)
    if player:hasSkill("joy__longnu") and table.contains(player.player_cards[Player.Hand], card.id) then
      local mark = player:getTableMark( "@joy__longnu-turn")
      return table.contains(mark, card:getColorString())
    end
  end,
  view_as = function(self, card, player)
    local c = Fk:cloneCard(card.color == Card.Red and "fire__slash" or "thunder__slash", card.suit, card.number)
    c.skillName = "joy__longnu"
    return c
  end,
}
local joy__longnu_targetmod = fk.CreateTargetModSkill{
  name = "#joy__longnu_targetmod",
  bypass_distances =  function(self, player, skill, card, to)
    return card and card.name == "fire__slash" and table.contains(card.skillNames, "joy__longnu")
  end,
  bypass_times = function(self, player, skill, scope, card, to)
    return card and card.name == "thunder__slash" and table.contains(card.skillNames, "joy__longnu")
  end,
}
joy__longnu:addRelatedSkill(joy__longnu_filter)
joy__longnu:addRelatedSkill(joy__longnu_targetmod)
joy__godliubei:addSkill(joy__longnu)
local joy__jieying = fk.CreateTriggerSkill{
  name = "joy__jieying",
  events = {fk.BeforeChainStateChange, fk.EventPhaseStart, fk.GameStart, fk.Damaged},
  frequency = Skill.Compulsory,
  can_trigger = function(self, event, target, player, data)
    if not player:hasSkill(self) then return false end
    if event == fk.BeforeChainStateChange then
      return target == player and player.chained
    elseif event == fk.EventPhaseStart then
      return target == player and player.phase == Player.Finish and table.find(player.room.alive_players, function(p)
        return p ~= player and not p.chained
      end)
    elseif event == fk.Damaged then
      return target == player
    else
      return not player.chained
    end
  end,
  on_use = function(self, event, target, player, data)
    if event == fk.GameStart then
      player:setChainState(true)
    elseif event == fk.BeforeChainStateChange then
      return true
    elseif event == fk.Damaged then
      player:drawCards(1, self.name)
    else
      local room = player.room
      local targets = table.filter(room.alive_players, function(p)
        return p ~= player and not p.chained
      end)
      if #targets == 0 then return false end
      local tos = room:askForChoosePlayers(player, table.map(targets, Util.IdMapper), 1, 1, "#joy__jieying-target", self.name, false)
      if #tos > 0 then
        room:getPlayerById(tos[1]):setChainState(true)
      end
    end
  end,
}
local joy__jieying_maxcards = fk.CreateMaxCardsSkill{
  name = "#joy__jieying_maxcards",
  correct_func = function(self, player)
    if player.chained then
      local num = #table.filter(Fk:currentRoom().alive_players, function(p)
        return p:hasSkill(joy__jieying)
      end)
      return 2 * num
    end
  end,
}
joy__jieying:addRelatedSkill(joy__jieying_maxcards)
joy__godliubei:addSkill(joy__jieying)
Fk:loadTranslationTable{
  ["joy__godliubei"] = "神刘备",
  ["#joy__godliubei"] = "誓守桃园义",

  ["joy__longnu"] = "龙怒",
  [":joy__longnu"] = "锁定技，出牌阶段开始时，你须选一项：1.失去1点体力并摸两张牌，你的红色手牌于本回合均视为无距离限制的火【杀】；2.扣减1点体力上限，你的黑色手牌于本回合均视为无次数限制的雷【杀】。",
  ["joy__jieying"] = "结营",
  [":joy__jieying"] = "锁定技，你始终处于横置状态；每当你受到伤害时，摸一张牌；处于连环状态的角色手牌上限+2；结束阶段，你横置一名其他角色。",

  ["#joy__longnu_filter"] = "龙怒",
  ["joy__longnu_red"] = "失去体力并摸牌，红色手牌视为火杀",
  ["joy__longnu_black"] = "减体力上限，黑色手牌视为雷杀",
  ["@joy__longnu-turn"] = "龙怒",
  ["#joy__jieying-target"] = "结营：横置一名其他角色",
}

local goddiaochan = General(extension, "joy__goddiaochan", "god", 3, 3, General.Female)
local joy__meihun = fk.CreateTriggerSkill{
  name = "joy__meihun",
  anim_type = "control",
  events = {fk.EventPhaseStart, fk.TargetConfirmed},
  can_trigger = function(self, event, target, player, data)
    if target == player and player:hasSkill(self.name) then
      if event == fk.EventPhaseStart then
        return player.phase == Player.Finish
      elseif event == fk.TargetConfirmed then
        return data.card.trueName == "slash" and player:getMark("joy__meihun-turn") == 0
      end
    end
  end,
  on_trigger = function(self, event, target, player, data)
    if event == fk.TargetConfirmed then
      player.room:setPlayerMark(player, "joy__meihun-turn", 1)
    end
    self:doCost(event, target, player, data)
  end,
  on_cost = function(self, event, target, player, data)
    local room = player.room
    local targets = table.filter(room:getOtherPlayers(player), function(p) return not p:isNude() end)
    if #targets == 0 then return end
    local to = room:askForChoosePlayers(player, table.map(targets, Util.IdMapper), 1, 1, "#joy__meihun-choose", self.name, true)
    if #to > 0 then
      self.cost_data = to[1]
      return true
    end
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    local to = room:getPlayerById(self.cost_data)
    local choice = room:askForChoice(player, {"log_spade", "log_heart", "log_club", "log_diamond"}, self.name, "#joy__meihun-choice::"..to.id)
    local cards = {}
    for _, id in ipairs(to:getCardIds("he")) do
      if Fk:getCardById(id):getSuitString(true) == choice then
        table.insert(cards, id)
      end
    end
    if #cards > 0 then
      room:moveCardTo(cards, Card.PlayerHand, player, fk.ReasonGive, self.name, nil, false, to.id)
    elseif not to:isKongcheng() then
      local id = room:askForCardChosen(player, to, { card_data = { { "$Hand", to:getCardIds(Player.Hand) }  } }, self.name)
      room:moveCardTo(id, Card.PlayerHand, player, fk.ReasonPrey, self.name, nil, false, player.id)
    end
  end,
}
local joy__huoxin = fk.CreateActiveSkill{
  name = "joy__huoxin",
  anim_type = "control",
  card_num = 1,
  target_num = 2,
  prompt = "#joy__huoxin",
  can_use = function(self, player)
    return player:usedSkillTimes(self.name, Player.HistoryPhase) == 0
  end,
  card_filter = function(self, to_select, selected)
    return #selected == 0 and not Self:prohibitDiscard(Fk:getCardById(to_select))
  end,
  target_filter = function(self, to_select, selected, selected_cards)
    if #selected < 2 and #selected_cards == 1 and not Fk:currentRoom():getPlayerById(to_select):isKongcheng() then
      if to_select == Self.id then
        if Fk:currentRoom():getCardArea(selected_cards[1]) == Player.Hand then
          return Self:getHandcardNum() > 1
        else
          return not Self:isKongcheng()
        end
      else
        return true
      end
    end
  end,
  on_use = function(self, room, effect)
    local player = room:getPlayerById(effect.from)
    room:throwCard(effect.cards, self.name, player, player)
    local targets = table.map(effect.tos, function(id) return room:getPlayerById(id) end)
    local pindian = targets[1]:pindian({targets[2]}, self.name)
    if player.dead then return end
    local losers = {}
    if pindian.results[targets[2].id].winner == targets[1] then
      losers = {targets[2]}
    elseif pindian.results[targets[2].id].winner == targets[2] then
      losers = {targets[1]}
    else
      losers = targets
    end
    local suits = {"", "spade", "heart", "club", "diamond"}
    local choices = table.map(suits, function(s) return Fk:translate("log_"..s) end)
    choices[1] = "Cancel"
    local choice = room:askForChoice(player, choices, self.name, "#joy__huoxin-choice")
    if choice ~= "Cancel" then
      local suit = suits[table.indexOf(choices, choice)]
      for _, p in ipairs(losers) do
        if player.dead then return end
        if not p.dead then
          room:doIndicate(player.id, {p.id})
          if table.find(p:getCardIds("he"), function(id) return Fk:getCardById(id):getSuitString() == suit end) then
            local choice2 = room:askForChoice(p, {"joy__huoxin_prey:::"..choice, "joy__huoxin_mark"}, self.name,
              "#joy__huoxin2-choice::"..p.id)
            if choice2[13] == "p" then
              local dummy = Fk:cloneCard("dilu")
              for _, id in ipairs(p:getCardIds("he")) do
                if Fk:getCardById(id):getSuitString() == suit then
                  dummy:addSubcard(id)
                end
              end
              if #dummy.subcards > 0 then
                room:obtainCard(player, dummy, false, fk.ReasonGive)
              end
            else
              room:setPlayerMark(p, "@joy__huoxin-turn", choice)
            end
          else
            room:setPlayerMark(p, "@joy__huoxin-turn", choice)
          end
        end
      end
    end
  end,
}
local joy__huoxin_prohibit = fk.CreateProhibitSkill{
  name = "#joy__huoxin_prohibit",
  prohibit_use = function(self, player, card)
    return player:getMark("@joy__huoxin-turn") ~= 0 and player:getMark("@joy__huoxin-turn") == card:getSuitString(true)
  end,
  prohibit_response = function(self, player, card)
    return player:getMark("@joy__huoxin-turn") ~= 0 and player:getMark("@joy__huoxin-turn") == card:getSuitString(true)
  end,
}
joy__huoxin:addRelatedSkill(joy__huoxin_prohibit)
goddiaochan:addSkill(joy__meihun)
goddiaochan:addSkill(joy__huoxin)
Fk:loadTranslationTable{
  ["joy__goddiaochan"] = "神貂蝉",
  ["joy__meihun"] = "魅魂",
  [":joy__meihun"] = "结束阶段或每回合你首次成为【杀】的目标后，你可以声明一种花色，令一名其他角色交给你所有此花色的牌，若其没有，则你观看"..
  "其手牌并获得其中一张。",
  ["joy__huoxin"] = "惑心",
  [":joy__huoxin"] = "出牌阶段限一次，你可以弃置一张牌令两名角色拼点，然后你可以声明一种花色，令没赢的角色交给你此花色的所有牌"..
  "或获得此花色的“魅惑”标记。有“魅惑”的角色不能使用或打出对应花色的牌直到回合结束。",
  ["#joy__meihun-choose"] = "魅魂：你可以令一名其他角色交给你指定花色的所有牌，或你观看并获得其一张手牌",
  ["#joy__meihun-choice"] = "魅魂：选择令 %dest 交给你的花色",
  ["#joy__huoxin"] = "惑心：弃置一张牌令两名角色拼点，没赢的角色交给你声明花色的牌或获得“魅惑”标记",
  ["#joy__huoxin-choice"] = "惑心：你可以声明一种花色，令没赢的角色交给你此花色的牌或获得“魅惑”标记",
  ["#joy__huoxin2-choice"] = "惑心：选择对 %dest 执行的一项",
  ["joy__huoxin_prey"] = "令其交给你所有%arg牌",
  ["joy__huoxin_mark"] = "令其获得“魅惑”标记",
  ["@joy__huoxin-turn"] = "魅惑",
}

-- OL活动场

local godzhenji = General(extension, "joy__godzhenji", "god", 3, 3, General.Female)
local joy__shenfu = fk.CreateTriggerSkill{
  name = "joy__shenfu",
  anim_type = "control",
  events = {fk.EventPhaseStart},
  can_trigger = function(self, event, target, player, data)
    return target == player and player:hasSkill(self) and player.phase == Player.Finish
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    local n = 0
    if player:getHandcardNum() % 2 == 1 then
      while true do
        local tos = room:askForChoosePlayers(player, table.map(room:getOtherPlayers(player), Util.IdMapper), 1, 1, "#shenfu-damage", self.name, true)
        if #tos == 0 then break end
        n = n + 1
        local to = room:getPlayerById(tos[1])
        room:damage{
          from = player,
          to = to,
          damage = 1,
          damageType = fk.ThunderDamage,
          skillName = self.name,
        }
        if not to.dead then
          break
        end
      end
    else
      while true do
        local tos = room:askForChoosePlayers(player, table.map(table.filter(room.alive_players, function(p)
          return p:getMark("joy__shenfu-turn") == 0 end), Util.IdMapper), 1, 1, "#shenfu-hand", self.name, true)
        if #tos == 0 then break end
        n = n + 1
        local to = room:getPlayerById(tos[1])
        room:setPlayerMark(to, "joy__shenfu-turn", 1)
        if to:isKongcheng() then
          to:drawCards(1, self.name)
        else
          local choice = room:askForChoice(player, {"shenfu_draw", "shenfu_discard"}, self.name)
          if choice == "shenfu_draw" then
            to:drawCards(1, self.name)
          else
            local card = room:askForCardsChosen(player, to, 1, 1, "he", self.name)
            room:throwCard(card, self.name, to, player)
          end
        end
        if to:getHandcardNum() ~= to.hp then
          break
        end
      end
    end
    if not player.dead and n > 0 then
      player:drawCards(math.min(n, 5), self.name)
    end
  end,
}
local joy__qixian = fk.CreateTriggerSkill{
  name = "joy__qixian",
  anim_type = "control",
  events = {fk.EventPhaseEnd},
  can_trigger = function(self, event, target, player, data)
    return target == player and player:hasSkill(self) and player.phase == Player.Play and not player:isKongcheng()
  end,
  on_cost = function (self, event, target, player, data)
    local card = player.room:askForCard(player, 1, 1, false, self.name, true, ".", "#joy__qixian-card")
    if #card > 0 then
      self.cost_data = card[1]
      return true
    end
  end,
  on_use = function(self, event, target, player, data)
    player:addToPile(self.name, self.cost_data, false, self.name)
  end,
}
local joy__qixian_delay = fk.CreateTriggerSkill{
  name = "#joy__qixian_delay",
  mute = true,
  events = {fk.TurnEnd},
  frequency = Skill.Compulsory,
  can_trigger = function(self, event, target, player, data)
    return target == player and #player:getPile("joy__qixian") > 0
  end,
  on_use = function(self, event, target, player, data)
    local dummy = Fk:cloneCard("slash")
    dummy:addSubcards(player:getPile("joy__qixian"))
    player.room:obtainCard(player, dummy, false, fk.ReasonPrey)
  end,
}
local joy__qixian_maxcards = fk.CreateMaxCardsSkill{
  name = "#joy__qixian_maxcards",
  frequency = Skill.Compulsory,
  fixed_func = function (self, player)
    if player:hasSkill(joy__qixian) then
      return 7
    end
  end,
}
local joy__feifu = fk.CreateViewAsSkill{
  name = "joy__feifu",
  anim_type = "defensive",
  pattern = "jink",
  card_filter = function(self, to_select, selected)
    return #selected == 0 and Fk:getCardById(to_select).color == Card.Black
  end,
  view_as = function(self, cards)
    if #cards ~= 1 then return end
    local card = Fk:cloneCard("jink")
    card.skillName = self.name
    card:addSubcard(cards[1])
    return card
  end,
}
godzhenji:addSkill(joy__shenfu)
joy__qixian:addRelatedSkill(joy__qixian_maxcards)
joy__qixian:addRelatedSkill(joy__qixian_delay)
godzhenji:addSkill(joy__qixian)
godzhenji:addSkill(joy__feifu)
Fk:loadTranslationTable{
  ["joy__godzhenji"] = "神甄姬",
  ["joy__shenfu"] = "神赋",
  [":joy__shenfu"] = "结束阶段，如果你的手牌数量为：奇数，可对一名其他角色造成1点雷电伤害，若造成其死亡，你可重复此流程；"..
  "偶数，可令一名角色摸一张牌或你弃置其一张牌，若执行后该角色的手牌数等于其体力值，你可重复此流程（不能对本回合指定过的目标使用）。"..
  "然后你摸X张牌（X为你本回合执行〖神赋〗流程的次数，最大为5）。",
  ["joy__qixian"] = "七弦",
  [":joy__qixian"] = "锁定技，你的手牌上限为7。出牌阶段结束时，你可以将一张手牌移出游戏直到回合结束。",
  ["#joy__qixian_delay"] = "七弦",
  ["#joy__qixian-card"] = "七弦：你可以将一张手牌移出游戏直到回合结束",
  ["joy__feifu"] = "飞凫",
  [":joy__feifu"] = "你可以将一张黑色牌当【闪】使用或打出。",
}


local joy__goddaxiaoqiao = General(extension, "joy__goddaxiaoqiao", "god", 4, 4, General.Female)

local joy__shuangshu = fk.CreateTriggerSkill{
  name = "joy__shuangshu",
  events = {fk.EventPhaseStart},
  can_trigger = function(self, event, target, player, data)
    return player:hasSkill(self) and target == player and player.phase == Player.Start
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    local cards = room:getNCards(2)
    local get = true
    player:showCards(cards)
    for i = #cards, 1, -1 do
      local id = cards[i]
      table.insert(room.draw_pile, 1, id)
      if Fk:getCardById(id).color ~= Card.Black then
        get = false
        if Fk:getCardById(id).suit == Card.Diamond then
          room:setCardEmotion(id, "judgegood")
          room:setPlayerMark(player, "joy__shuangshu_pt-turn", 1)
        elseif Fk:getCardById(id).suit == Card.Heart then
          room:setCardEmotion(id, "judgegood")
          room:setPlayerMark(player, "joy__shuangshu_yz-turn", 1)
        end
      end
    end
    if get then
      room:moveCardTo(cards, Card.PlayerHand, player, fk.ReasonPrey, self.name)
    end
  end,
}
joy__goddaxiaoqiao:addSkill(joy__shuangshu)

local joy__pinting = fk.CreateTriggerSkill{
  name = "joy__pinting",
  events = {fk.EventPhaseStart},
  can_trigger = function(self, event, target, player, data)
    return player:hasSkill(self) and target == player and player.phase == Player.Play
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    local n = 2 + player:getMark("joy__shuangshu_pt-turn")
    local all_choices = {}
    for i = 1, 4 do
      table.insert(all_choices, "joy__pinting_choice"..i)
    end
    local choices = room:askForChoices(player, all_choices, 1, n, self.name, "#joy__pinting-choice:::"..n)
    local list = {}
    for i = 1, 4 do
      if table.contains(choices, "joy__pinting_choice"..i) then
        table.insert(list, i)
      end
    end
    room:setPlayerMark(player, "@joy__pinting_choices-phase", table.concat(list, "-"))
    if table.contains(list, 1) and #room.logic:getEventsOfScope(GameEvent.UseCard, 1, function(e)
      return e.data[1].from == player.id
    end, Player.HistoryPhase) == 0 then
      room:setPlayerMark(player, "joy__pinting_tmd-phase", 1)
    end
  end,

  refresh_events = {fk.AfterCardUseDeclared},
  can_refresh = function (self, event, target, player, data)
    return target == player and player:getMark("joy__pinting_tmd-phase") > 0
  end,
  on_refresh = function (self, event, target, player, data)
    player.room:setPlayerMark(player, "joy__pinting_tmd-phase", 0)
  end,
}
local joy__pinting_delay = fk.CreateTriggerSkill{
  name = "#joy__pinting_delay",
  events = {fk.CardUsing, fk.CardUseFinished},
  can_trigger = function(self, event, target, player, data)
    local mark = player:getMark("@joy__pinting_choices-phase")
    if target == player and mark ~= 0 then
      local events = player.room.logic:getEventsOfScope(GameEvent.UseCard, 4, function(e)
        return e.data[1].from == player.id
      end, Player.HistoryPhase)
      if event == fk.CardUseFinished then
        if string.find(mark, "3") and events[3] and events[3].data[1] == data then
          self.cost_data = 3
          return true
        end
      else
        if string.find(mark, "2") and events[2] and events[2].data[1] == data then
          local place = player.room:getCardArea(data.card)
          if place == Card.Processing or place == Card.PlayerEquip or place == Card.PlayerJudge then
            self.cost_data = 2
            return true
          end
        elseif string.find(mark, "4") and events[4] and events[4].data[1] == data then
          self.cost_data = 4
          return true
        end
      end
    end
  end,
  on_cost = Util.TrueFunc,
  on_use = function(self, event, target, player, data)
    local room = player.room
    if self.cost_data == 2 then
      room:moveCardTo(data.card, Card.PlayerHand, player, fk.ReasonPrey, "joy__pinting")
    elseif self.cost_data == 3 then
      player:drawCards(2, "joy__pinting")
    else
      local name = Fk:cloneCard(data.card.name)
      local use ={
        from = player.id,
        tos = data.tos,
        card = name,
        extraUse = true
      }
      room:useCard(use)
    end
  end,
}
local joy__pinting_targetmod = fk.CreateTargetModSkill{
  name = "#joy__pinting_targetmod",
  bypass_distances = function(self, player)
    return player:getMark("joy__pinting_tmd-phase") > 0
  end,
}
joy__pinting:addRelatedSkill(joy__pinting_delay)
joy__pinting:addRelatedSkill(joy__pinting_targetmod)
joy__goddaxiaoqiao:addSkill(joy__pinting)

---@param room Room
local getYizhengChoices = function (room, except)
  local choices = {}
  local map = {["weapon"] = {Card.SubtypeWeapon}, ["armor"] = {Card.SubtypeArmor},
  ["equip_horse"] = {Card.SubtypeOffensiveRide, Card.SubtypeDefensiveRide}}
  for _, p in ipairs(room.alive_players) do
    for str, sub_types in pairs(map) do
      if not table.contains(choices, str) then
        for _, s in ipairs(sub_types) do
          local id = p:getEquipment(s)
          if id and table.find(room.alive_players, function (p2) return p:canMoveCardInBoardTo(p2, id) end) then
            table.insert(choices, str)
            break
          end
        end
      end
    end
    if #choices == 3 then break end
  end
  table.removeOne(choices, except)
  return choices
end

local doYizheng = function (player, dat)
  local room = player.room
  local from = room:getPlayerById(dat.targets[1])
  local to = room:getPlayerById(dat.targets[2])
  local choice = dat.interaction
  local map = {["weapon"] = {Card.SubtypeWeapon}, ["armor"] = {Card.SubtypeArmor},
  ["equip_horse"] = {Card.SubtypeOffensiveRide, Card.SubtypeDefensiveRide}}
  local sub_types =  map[choice]
  local cards = {}
  for _, s in ipairs(sub_types) do
    local id = from:getEquipment(s)
    if id and to:getEquipment(s) == nil then
      table.insert(cards, id)
    end
  end
  if #cards == 0 then return end
  local cardId = room:askForCardChosen(player, from, { card_data = { { from.general, cards }  } }, "joy__yizhengg")
  room:moveCardTo(cardId, Card.PlayerEquip, to, fk.ReasonPut, "joy__yizhengg", nil, true, player.id)
end

local joy__yizhengg = fk.CreateTriggerSkill{
  name = "joy__yizhengg",
  events = {fk.EventPhaseEnd},
  can_trigger = function(self, event, target, player, data)
    return player:hasSkill(self) and target == player and player.phase == Player.Play
  end,
  on_cost = function (self, event, target, player, data)
    local room = player.room
    local choices = getYizhengChoices(room)
    if #choices > 0 then
      local _,dat = room:askForUseActiveSkill(player, "joy__yizhengg_active", "#joy__yizhengg-move", true, {joy__yizhengg_choices = choices})
      if dat then
        self.cost_data = dat
        return true
      end
    end
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    local dat = self.cost_data
    doYizheng (player, dat)
    local once = true
    if player:getMark("joy__shuangshu_yz-turn") > 0 then
      local choices = getYizhengChoices(room, dat.interaction)
      if #choices > 0 then
        local _, _dat = room:askForUseActiveSkill(player, "joy__yizhengg_active", "#joy__yizhengg-move", true, {joy__yizhengg_choices = choices})
        if _dat then
          doYizheng (player, _dat)
          once = false
        end
      end
    end
    if player.dead then return end
    if once then
      if player:isWounded() then
        room:recover { num = 1, skillName = self.name, who = player, recoverBy = player}
      end
    else
      room:setPlayerMark(player, "@@joy__yizhengg", 1)
    end
  end,
}
local joy__yizhengg_active = fk.CreateActiveSkill{
  name = "joy__yizhengg_active",
  card_num = 0,
  target_num = 2,
  interaction = function(self,player)
    return UI.ComboBox {choices = self.joy__yizhengg_choices or {} , all_choices = {"weapon","armor","equip_horse"} }
  end,
  card_filter = Util.FalseFunc,
  target_filter = function(self, to_select, selected)
    local choice = self.interaction.data
    if not choice then return end
    local map = {["weapon"] = {Card.SubtypeWeapon}, ["armor"] = {Card.SubtypeArmor},
    ["equip_horse"] = {Card.SubtypeOffensiveRide, Card.SubtypeDefensiveRide}}
    local sub_types =  map[choice]
    local to = Fk:currentRoom():getPlayerById(to_select)
    if #selected == 0 then
      return table.find(sub_types, function(s) return to:getEquipment(s) end)
    elseif #selected == 1 then
      local first = Fk:currentRoom():getPlayerById(selected[1])
      return table.find(sub_types, function(s) return first:getEquipment(s) and to:getEquipment(s) == nil end)
    end
  end,
}
local joy__yizhengg_delay = fk.CreateTriggerSkill{
  name = "#joy__yizhengg_delay",
  mute = true,
  events = {fk.AfterCardsMove},
  can_trigger = function(self, event, target, player, data)
    if player.dead or player:getMark("@@joy__yizhengg") == 0 then return false end
    local x = 0
    local color
    for _, move in ipairs(data) do
      if move.from == player.id then
        for _, info in ipairs(move.moveInfo) do
          if info.fromArea == Card.PlayerHand or info.fromArea == Card.PlayerEquip then
            x = x + 1
          end
        end
      end
    end
    if x > 0 then
      self.cost_data = x
      return true
    end
  end,
  on_cost = Util.TrueFunc,
  on_use = function(self, event, target, player, data)
    player:drawCards(self.cost_data, "joy__yizhengg")
  end,

  refresh_events = {fk.TurnStart},
  can_refresh = function (self, event, target, player, data)
    return target == player and player:getMark("@@joy__yizhengg") > 0
  end,
  on_refresh = function (self, event, target, player, data)
    player.room:setPlayerMark(player, "@@joy__yizhengg", 0)
  end,
}
Fk:addSkill(joy__yizhengg_active)
joy__yizhengg:addRelatedSkill(joy__yizhengg_delay)
joy__goddaxiaoqiao:addSkill(joy__yizhengg)

Fk:loadTranslationTable{
  ["joy__goddaxiaoqiao"] = "神大小乔",

  ["joy__shuangshu"] = "双姝",
  [":joy__shuangshu"] = "准备阶段，你可以展示牌堆顶的2张牌，若包含：方块：本回合“娉婷”可选择的选项个数+1；红桃：本回合“移筝”可选择的选项个数+1；只有黑色牌：你获得展示的牌。",

  ["joy__pinting"] = "娉婷",
  [":joy__pinting"] = "出牌阶段开始时，你可选择以下选项中的至多两项：1、你使用的第一张牌无距离限制；2、你使用的第二张牌返还到你的手牌；3、你使用的第三张牌结算后摸两张牌；4、你使用的第四张牌额外结算一次。",
  ["joy__pinting_choice1"] = "第一张牌无距离限制",
  ["joy__pinting_choice2"] = "第二张牌返还到你的手牌",
  ["joy__pinting_choice3"] = "第三张牌结算后摸两张牌",
  ["joy__pinting_choice4"] = "第四张牌额外结算一次",
  ["@joy__pinting_choices-phase"] = "娉婷",
  ["#joy__pinting-choice"] = "娉婷：请选择至多 %arg 项",
  ["#joy__pinting_delay"] = "娉婷",

  ["joy__yizhengg"] = "移筝", -- 区别义争
  [":joy__yizhengg"] = "你的出牌阶段结束时，你可选择以下选项中的至多一项：1、移动场上的一张武器牌；2、移动场上的一张防具牌；3、移动场上的一张坐骑牌。若你以此法移动了：一张牌，回复1点体力；两张牌，直到你的下回合开始，你失去一张牌时摸一张牌。",
  ["#joy__yizhengg_delay"] = "移筝",
  ["@@joy__yizhengg"] = "移筝",
  ["joy__yizhengg_active"] = "移筝",
  ["#joy__yizhengg-move"] = "移筝：你可移动场上一张牌",
}

local godhuatuo = General(extension, "joy__godhuatuo", "god", 1)

local joy__jishi = fk.CreateTriggerSkill{
  name = "joy__jishi",
  anim_type = "support",
  events = {fk.GameStart, fk.AfterCardsMove, fk.EnterDying},
  can_trigger = function (self, event, target, player, data)
    if not player:hasSkill(self) then return false end
    if event == fk.EnterDying then
      return player:getMark("@joy__remedy") > 0
    else
      if player:getMark("@joy__remedy") > 2 then return false end
      local n = 0
      if event == fk.GameStart then
        n = 3
      elseif player ~= player.room.current then
        for _, move in ipairs(data) do
          if move.from == player.id then
            for _, info in ipairs(move.moveInfo) do
              if info.fromArea == Card.PlayerHand and Fk:getCardById(info.cardId).color == Card.Red then
                n = n + 1
              end
            end
          end
        end
      end
      if n > 0 then
        self.cost_data = n
        return true
      end
    end
  end,
  on_cost = function (self, event, target, player, data)
    if event == fk.EnterDying then
      return player.room:askForSkillInvoke(player, self.name, nil, "#joy__jishi-invoke:"..target.id)
    end
    return true
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    if event == fk.EnterDying then
      room:removePlayerMark(player, "@joy__remedy")
      room:recover { num = 1 - target.hp, skillName = self.name, who = target, recoverBy = player }
    else
      room:setPlayerMark(player, "@joy__remedy", math.min(3, player:getMark("@joy__remedy") + self.cost_data))
    end
  end,
}
local joy__jishi_maxcards = fk.CreateMaxCardsSkill{
  name = "#joy__jishi_maxcards",
  correct_func = function(self, player)
    if player:hasSkill(joy__jishi) then
      return 3
    end
  end,
}
joy__jishi:addRelatedSkill(joy__jishi_maxcards)
godhuatuo:addSkill(joy__jishi)

local joy__taoxian = fk.CreateViewAsSkill{
  name = "joy__taoxian",
  anim_type = "support",
  pattern = "peach",
  card_filter = function(self, to_select, selected)
    return #selected == 0 and Fk:getCardById(to_select).suit == Card.Heart
  end,
  view_as = function(self, cards)
    if #cards ~= 1 then return nil end
    local c = Fk:cloneCard("peach")
    c.skillName = self.name
    c:addSubcard(cards[1])
    return c
  end,
}
local joy__taoxian_trigger = fk.CreateTriggerSkill{
  name = "#joy__taoxian_trigger",
  main_skill = joy__taoxian,
  events = {fk.CardUsing},
  can_trigger = function(self, event, target, player, data)
    return target ~= player and player:hasSkill(joy__taoxian) and data.card.name == "peach"
  end,
  on_cost = Util.TrueFunc,
  on_use = function(self, event, target, player, data)
    player:drawCards(1, "joy__taoxian")
  end,
}
joy__taoxian:addRelatedSkill(joy__taoxian_trigger)
godhuatuo:addSkill(joy__taoxian)

local joy__shenzhen = fk.CreateTriggerSkill{
  name = "joy__shenzhen",
  anim_type = "control",
  events = {fk.TurnStart},
  can_trigger = function(self, event, target, player, data)
    return target == player and player:hasSkill(self) and player:getMark("@joy__remedy") > 0
  end,
  on_cost = function(self, event, target, player, data)
    local _, dat = player.room:askForUseActiveSkill(player, "joy__shenzhen_active", "#joy__shenzhen-invoke", true)
    if dat then
      self.cost_data = dat
      return true
    end
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    local targets = self.cost_data.targets
    room:removePlayerMark(player, "@joy__remedy", #targets)
    room:sortPlayersByAction(targets)
    for _, id in ipairs(targets) do
      local p = room:getPlayerById(id)
      if not p.dead then
        if self.cost_data.interaction == "recover" then
          if not p.dead and p:isWounded() then
            room:recover { num = 1, skillName = self.name, who = p, recoverBy = player }
          end
        else
          room:loseHp(p, 1, self.name)
        end
      end
    end
  end,
}
local joy__shenzhen_active = fk.CreateActiveSkill{
  name = "joy__shenzhen_active",
  card_num = 0,
  min_target_num = 1,
  interaction = function(self,player)
    return UI.ComboBox {choices = {"recover", "loseHp"}}
  end,
  card_filter = Util.FalseFunc,
  target_filter = function (self, to_select, selected)
    return #selected < Self:getMark("@joy__remedy")
  end,
}
Fk:addSkill(joy__shenzhen_active)
godhuatuo:addSkill(joy__shenzhen)

Fk:loadTranslationTable{
  ["joy__godhuatuo"] = "神华佗",

  ["joy__jishi"] = "济世",
  [":joy__jishi"] = "游戏开始时，你获得3个“药”（至多拥有3个）。每当一名角色进入濒死状态时，你可以移去1个“药”令其回复体力至1点。当你于回合外失去红色手牌时，你获得等量“药”。你的手牌上限+3。",
  ["#joy__jishi-invoke"] = "济世：你可以移去1个“药”令 %src 回复体力至1点",
  ["@joy__remedy"] = "药",

  ["joy__taoxian"] = "桃仙",
  [":joy__taoxian"] = "你可以将一张红桃牌当【桃】使用，其他角色使用【桃】时，你摸一张牌。",
  ["#joy__taoxian_trigger"] = "桃仙",

  ["joy__shenzhen"] = "神针",
  [":joy__shenzhen"] = "回合开始时，你可以移去任意个“药”，然后选择一项：1. 令等量角色各回复1点体力；2. 令等量角色各失去1点体力。",
  ["joy__shenzhen_active"] = "神针",
  ["#joy__shenzhen-invoke"] = "神针：移去任意“药”，令等量角色回复或失去体力",
}

local goddianwei = General(extension, "joy__goddianwei", "god", 5)

local joy__shenwei = fk.CreateTriggerSkill{
  name = "joy__shenwei",
  anim_type = "support",
  events = {fk.TurnStart, fk.DamageInflicted},
  can_trigger = function(self, event, target, player, data)
    if event == fk.TurnStart then
      return target == player and player:hasSkill(self) and
      table.find(player.room.alive_players, function (p) return p:getMark("@@joy__secure") == 0 end)
    else
      return not player.dead and target:getMark("@@joy__secure") == player.id
    end
  end,
  on_cost = function (self, event, target, player, data)
    if event == fk.TurnStart then
      local targets = table.filter(player.room.alive_players, function (p) return p:getMark("@@joy__secure") == 0 end)
      if #targets == 0 then return false end
      local tos = player.room:askForChoosePlayers(player, table.map(targets, Util.IdMapper), 1, 1, "#joy__shenwei-choose", self.name, true)
      if #tos > 0 then
        self.cost_data = tos[1]
        return true
      end
    else
      return player.room:askForSkillInvoke(target, self.name, nil, "#joy__shenwei-invoke:"..player.id)
    end
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    if event == fk.TurnStart then
      room:setPlayerMark(room:getPlayerById(self.cost_data), "@@joy__secure", player.id)
    else
      room:setPlayerMark(target, "@@joy__secure", 0)
      room.logic:trigger("fk.MarkChanged", target, { name = "@@joy__secure", num = -1 })
      room:damage{
        from = data.from,
        to = player,
        damage = data.damage,
        damageType = data.damageType,
        skillName = data.skillName,
        chain = data.chain,
        card = data.card,
      }
      return true
    end
  end,

  refresh_events = {fk.Deathed, fk.EventLoseSkill},
  can_refresh = function (self, event, target, player, data)
    if event == fk.Deathed then
      return target == player and player:hasSkill(self, true, true)
    else
      return target == player and data == self
    end
  end,
  on_refresh = function (self, event, target, player, data)
    local room = player.room
    for _, p in ipairs(room.alive_players) do
      if p:getMark("@@joy__secure") == player.id then
        room:setPlayerMark(p, "@@joy__secure", 0)
      end
    end
  end,
}
goddianwei:addSkill(joy__shenwei)

local joy__elai = fk.CreateTriggerSkill{
  name = "joy__elai",
  anim_type = "offensive",
  frequency = Skill.Compulsory,
  events = {"fk.MarkChanged"},
  can_trigger = function(self, event, target, player, data)
    return player:hasSkill(self) and data.name == "@@joy__secure" and data.num < 0
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    local choices = {}
    if player:isWounded() then table.insert(choices, "recover") end
    local targets = table.filter(room.alive_players, function (p) return player:inMyAttackRange(p) end)
    if #targets > 0 then
      table.insert(choices, "joy__elai_damage")
    end
    if #choices == 0 then return false end
    table.insert(choices, "Cancel")
    local choice = room:askForChoice(player, choices, self.name)
    if choice == "joy__elai_damage" then
      local tos = player.room:askForChoosePlayers(player, table.map(targets, Util.IdMapper), 1, 1, "#joy__elai-choose", self.name, false)
      room:damage{
        from = player,
        to = room:getPlayerById(tos[1]),
        damage = 1,
        skillName = self.name,
      }
    elseif choice == "recover" then
      room:recover { num = 1, skillName = self.name, who = player, recoverBy = player }
    end
  end,
}
goddianwei:addSkill(joy__elai)

local joy__kuangxi = fk.CreateTriggerSkill{
  name = "joy__kuangxi",
  anim_type = "offensive",
  frequency = Skill.Compulsory,
  events = {fk.DamageCaused},
  can_trigger = function(self, event, target, player, data)
    return player:hasSkill(self) and target == player and
    table.find(player.room.alive_players, function (p) return p:getMark("@@joy__secure") > 0 end)
  end,
  on_use = function(self, event, target, player, data)
    data.damage = data.damage + 1
  end,
}
goddianwei:addSkill(joy__kuangxi)

Fk:loadTranslationTable{
  ["joy__goddianwei"] = "神典韦",

  ["joy__shenwei"] = "神卫",
  [":joy__shenwei"] = "回合开始时，你可以令一名没有“卫”标记的角色获得“卫”标记，该角色受到伤害时，可以移除此标记，将此伤害转移给你。",
  ["@@joy__secure"] = "卫",
  ["#joy__shenwei-choose"] = "神卫：令一名角色获得“卫”标记",
  ["#joy__shenwei-invoke"] = "神卫：你可以将伤害转移给 %src",

  ["joy__elai"] = "恶来",
  [":joy__elai"] = "锁定技，当一名角色的“卫”标记移除时，你可以选一项：1.回复一点体力；2.对攻击范围内一名角色造成1点伤害。",
  ["joy__elai_damage"] = "对攻击范围内一名角色造成伤害",
  ["#joy__elai-choose"] = "恶来：对攻击范围内一名角色造成1点伤害",

  ["joy__kuangxi"] = "狂袭",
  [":joy__kuangxi"] = "锁定技，每当你造成伤害时，若场上存在“卫”标记，此伤害+1。",
}

local godzhaoyun = General(extension, "joy__godzhaoyun", "god", 2)
local juejing = fk.CreateTriggerSkill{
  name = "joy__juejing",
  anim_type = "drawcard",
  frequency = Skill.Compulsory,
  events = {fk.EnterDying, fk.AfterDying},
  on_use = function(self, event, target, player, data)
    player:drawCards(1, self.name)
  end,
}
local juejing_maxcards = fk.CreateMaxCardsSkill{
  name = "#joy__juejing_maxcards",
  correct_func = function(self, player)
    if player:hasSkill(juejing) then
      return 3
    end
  end
}
juejing:addRelatedSkill(juejing_maxcards)
local longhun = fk.CreateViewAsSkill{
  name = "joy__longhun",
  pattern = "peach,slash,jink,nullification",
  card_filter = function(self, to_select, selected)
    if #selected == 2 then
      return false
    elseif #selected == 1 then
      return Fk:getCardById(to_select):compareSuitWith(Fk:getCardById(selected[1]))
    else
      local suit = Fk:getCardById(to_select).suit
      local c
      if suit == Card.Heart then
        c = Fk:cloneCard("peach")
      elseif suit == Card.Diamond then
        c = Fk:cloneCard("fire__slash")
      elseif suit == Card.Club then
        c = Fk:cloneCard("jink")
      elseif suit == Card.Spade then
        c = Fk:cloneCard("nullification")
      else
        return false
      end
      return (Fk.currentResponsePattern == nil and c.skill:canUse(Self, c)) or (Fk.currentResponsePattern and Exppattern:Parse(Fk.currentResponsePattern):match(c))
    end
  end,
  view_as = function(self, cards)
    if #cards == 0 or #cards > 2 then
      return nil
    end
    local suit = Fk:getCardById(cards[1]).suit
    local c
    if suit == Card.Heart then
      c = Fk:cloneCard("peach")
    elseif suit == Card.Diamond then
      c = Fk:cloneCard("fire__slash")
    elseif suit == Card.Club then
      c = Fk:cloneCard("jink")
    elseif suit == Card.Spade then
      c = Fk:cloneCard("nullification")
    else
      return nil
    end
    c.skillName = self.name
    c:addSubcards(cards)
    return c
  end,
  before_use = function(self, player, use)
    local num = #use.card.subcards
    if num == 2 then
      local suit = Fk:getCardById(use.card.subcards[1]).suit
      if suit == Card.Diamond then
        use.additionalDamage = (use.additionalDamage or 0) + 1
        player:drawCards(1, self.name)
      elseif suit == Card.Heart then
        use.additionalRecover = (use.additionalRecover or 0) + 1
        player:drawCards(1, self.name)
      end
    end
  end,
}
local longhun_obtaincard = fk.CreateTriggerSkill{
  name = "#joy__longhun_delay",
  events = {fk.CardUseFinished},
  mute = true,
  can_trigger = function(self, event, target, player, data)
    return target == player and table.contains(data.card.skillNames, "joy__longhun") and #data.card.subcards == 2 and Fk:getCardById(data.card.subcards[1]).color == Card.Black and not player.dead
  end,
  on_cost = function() return true end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    local from = room.current
      if from and not from.dead and not from:isNude() then
        room:doIndicate(player.id, {from.id})
        local card = room:askForCardChosen(player, from, "he", self.name)
        room:obtainCard(player, card, false, fk.ReasonPrey)
      end
  end,
}
longhun:addRelatedSkill(longhun_obtaincard)
godzhaoyun:addSkill(juejing)
godzhaoyun:addSkill(longhun)
Fk:loadTranslationTable{
  ["joy__godzhaoyun"] = "神赵云",
  ["#joy__godzhaoyun"] = "神威如龙",

  ["joy__juejing"] = "绝境",
  [":joy__juejing"] = "锁定技，你的手牌上限+3；当你进入濒死状态时或你的濒死结算结束后，你摸一张牌。",
  ["joy__longhun"] = "龙魂",
  ["#joy__longhun_delay"] = "龙魂",
  [":joy__longhun"] = "你可以将至多两张你的同花色的牌按以下规则使用或打出：红桃当【桃】，方块当火【杀】，梅花当【闪】，黑桃当【无懈可击】。"..
  "若你以此法使用或打出了两张：红色牌，此牌回复伤害基数+1，且你摸一张牌；黑色牌，你获得当前回合角色一张牌。",
}

local godganning = General(extension, "joy__godganning", "god", 3, 6)
local poxi = fk.CreateActiveSkill{
  name = "joy__poxi",
  anim_type = "control",
  prompt = "#joy__poxi-prompt",
  card_num = 0,
  target_num = 1,
  can_use = function(self, player)
    return player:usedSkillTimes(self.name, Player.HistoryPhase) < 1
  end,
  card_filter = function() return false end,
  target_filter = function(self, to_select, selected, selected_cards)
    return #selected == 0 and to_select ~= Self.id and not Fk:currentRoom():getPlayerById(to_select):isKongcheng()
  end,
  on_use = function(self, room, effect)
    local player = room:getPlayerById(effect.from)
    local target = room:getPlayerById(effect.tos[1])
    local player_hands = player:getCardIds("h")
    local target_hands = target:getCardIds("h")
    local cards = room:askForPoxi(player, "joy__poxi_discard", {
      { player.general, player_hands },
      { target.general, target_hands },
    }, nil, true)
    if #cards == 0 then return end
    local cards1 = table.filter(cards, function(id) return table.contains(player_hands, id) end)
    local cards2 = table.filter(cards, function(id) return table.contains(target_hands, id) end)
    local moveInfos = {}
    if #cards1 > 0 then
      table.insert(moveInfos, {
        from = player.id,
        ids = cards1,
        toArea = Card.DiscardPile,
        moveReason = fk.ReasonDiscard,
        proposer = effect.from,
        skillName = self.name,
      })
    end
    if #cards2 > 0 then
      table.insert(moveInfos, {
        from = target.id,
        ids = cards2,
        toArea = Card.DiscardPile,
        moveReason = fk.ReasonDiscard,
        proposer = effect.from,
        skillName = self.name,
      })
    end
    room:moveCards(table.unpack(moveInfos))
    if player.dead then return false end
    if #cards1 == 0 then
      room:changeMaxHp(player, -1)
    elseif #cards1 == 2 and player:isWounded() then
      room:recover({
        who = player,
        num = 1,
        recoverBy = player,
        skillName = self.name
      })
      if not player.dead then
        player:drawCards(1,self.name)
      end
    elseif #cards1 == 3 then
      room:drawCards(player, 3, self.name)
    end
    return false
  end,
}
Fk:addPoxiMethod{
  name = "joy__poxi_discard",
  card_filter = function(to_select, selected, data)
    local suit = Fk:getCardById(to_select).suit
    if suit == Card.NoSuit then return false end
    return not table.find(selected, function(id) return Fk:getCardById(id).suit == suit end)
    and not (Self:prohibitDiscard(Fk:getCardById(to_select)) and table.contains(data[1][2], to_select))
  end,
  feasible = function(selected)
    return #selected == 3
  end,
  prompt = function ()
    return "魄袭：弃置双方手里三张不同花色的牌"
  end
}
local gn_jieying = fk.CreateTriggerSkill{
  name = "joy__gn_jieying",
  anim_type = "drawcard",
  events = {fk.DrawNCards, fk.EventPhaseStart, fk.TurnStart},
  can_trigger = function(self, event, target, player, data)
    if not player:hasSkill(self) then return false end
    if event == fk.TurnStart then
      return player == target and table.every(player.room.alive_players, function (p)
        return p:getMark("@@joy__jieying_camp") == 0 end)
    elseif event == fk.EventPhaseStart and target.phase ~= Player.Finish then
      return false
    end
    return target:getMark("@@joy__jieying_camp") > 0
  end,
  on_cost = function(self, event, target, player, data)
    if event == fk.EventPhaseStart and player == target then
      local to = player.room:askForChoosePlayers(player, table.map(player.room:getOtherPlayers(player), function (p)
        return p.id end), 1, 1, "#joy__gn_jieying-choose", self.name, true)
      if #to > 0 then
        self.cost_data = to[1]
        return true
      end
      return false
    end
    return true
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    if event == fk.TurnStart then
      room:addPlayerMark(player, "@@joy__jieying_camp")
    elseif event == fk.DrawNCards then
      data.n = data.n + 1
    elseif event == fk.EventPhaseStart then
      if player == target then
        local tar = room:getPlayerById(self.cost_data)
        room:setPlayerMark(player, "@@joy__jieying_camp", 0)
        room:addPlayerMark(tar, "@@joy__jieying_camp")
      else
        room:setPlayerMark(target, "@@joy__jieying_camp", 0)
        if not target:isKongcheng() then
          local dummy = Fk:cloneCard("dilu")
          dummy:addSubcards(target.player_cards[Player.Hand])
          room:obtainCard(player.id, dummy, false, fk.ReasonPrey)
        end
      end
    end
    return false
  end,

  refresh_events = {fk.BuryVictim, fk.EventLoseSkill},
  can_refresh = function(self, event, target, player, data)
    return (event == fk.BuryVictim or data == self) and player:getMark("@@joy__jieying_camp") > 0
  end,
  on_refresh = function(self, event, target, player, data)
    local room = player.room
    if table.every(room.alive_players, function (p) return not p:hasSkill(self.name, true) end) then
      room:setPlayerMark(player, "@@joy__jieying_camp", 0)
    end
  end,
}
local gn_jieying_targetmod = fk.CreateTargetModSkill{
  name = "#joy__gn_jieying_targetmod",
  residue_func = function(self, player, skill, scope)
    if skill.trueName == "slash_skill" and player:getMark("@@joy__jieying_camp") > 0 and scope == Player.HistoryPhase then
      return #table.filter(Fk:currentRoom().alive_players, function (p) return p:hasSkill(gn_jieying.name) end)
    end
  end,
}
local gn_jieying_maxcards = fk.CreateMaxCardsSkill{
  name = "#joy__gn_jieying_maxcards",
  correct_func = function(self, player)
    if player:getMark("@@joy__jieying_camp") > 0 then
      return #table.filter(Fk:currentRoom().alive_players, function (p) return p:hasSkill(gn_jieying.name) end)
    else
      return 0
    end
  end,
}
gn_jieying:addRelatedSkill(gn_jieying_targetmod)
gn_jieying:addRelatedSkill(gn_jieying_maxcards)
godganning:addSkill(poxi)
godganning:addSkill(gn_jieying)
Fk:loadTranslationTable{
  ["joy__godganning"] = "神甘宁",
  ["#joy__godganning"] = "江表之力牧",

  ["joy__poxi"] = "魄袭",
  [":joy__poxi"] = "出牌阶段限一次，你可以观看一名其他角色的手牌，然后你可以弃置你与其手里共计三张不同花色的牌。若如此做，根据此次弃置你的牌数量执行以下效果：没有，体力上限减1；两张，回复1点体力并摸一张牌；三张，摸三张牌。",
  ["joy__gn_jieying"] = "劫营",
  [":joy__gn_jieying"] = "回合开始时，若没有角色有“营”标记，你获得一个“营”标记；结束阶段你可以将“营”标记交给一名其他角色；"..
  "有“营”的角色摸牌阶段多摸一张牌、使用【杀】的次数上限+1、手牌上限+1。有“营”的其他角色的结束阶段，移去“营”，然后你获得其所有手牌。",

  ["joy__poxi_discard"] = "魄袭",
  ["#joy__poxi-prompt"] = "魄袭：选择一名有手牌的其他角色，并可弃置你与其手牌中共计三张花色各不相同的牌",
  ["@@joy__jieying_camp"] = "营",
  ["#joy__poxi-choose"] = "魄袭：从双方的手牌中选出四张不同花色的牌弃置，或者点取消",
  ["#joy__gn_jieying-choose"] = "劫营：你可将营标记交给其他角色",
}

local godguanyu = General(extension, "joy__godguanyu", "god", 5)
local joy__wushen = fk.CreateViewAsSkill{
  name = "joy__wushen",
  anim_type = "offensive",
  pattern = "slash",
  card_filter = function(self, to_select, selected)
    if #selected == 1 then return false end
    return Fk:getCardById(to_select).suit == Card.Heart
  end,
  view_as = function(self, cards)
    if #cards ~= 1 then
      return nil
    end
    local c = Fk:cloneCard("slash")
    c.skillName = self.name
    c:addSubcard(cards[1])
    return c
  end,
}
local wushen_targetmod = fk.CreateTargetModSkill{
  name = "#joy__wushen_targetmod",
  anim_type = "offensive",
  bypass_distances = function(self, player, skill, card)
    return player:hasSkill(joy__wushen) and skill.trueName == "slash_skill" and card.suit == Card.Heart
  end,
}
local wushen_trigger = fk.CreateTriggerSkill{
  name = "#joy__wushen_trigger",
  main_skill = joy__wushen,
  mute = true,
  events = {fk.AfterCardUseDeclared},
  can_trigger = function(self, event, target, player, data)
    if target == player and player:hasSkill(self) then
      return  data.card.trueName == "slash" and data.card.suit == Card.Heart
    end
  end,
  on_cost = Util.TrueFunc,
  on_use = function(self, event, target, player, data)
    local room = player.room
      room:notifySkillInvoked(player, "joy__wushen", "offensive")
      data.additionalDamage = (data.additionalDamage or 0) + 1
  end,
}
local wuhun = fk.CreateTriggerSkill{
  name = "joy__wuhun",
  anim_type = "offensive",
  frequency = Skill.Compulsory,
  events = {fk.Damaged,fk.AfterDying, fk.Death},
  can_trigger = function(self, event, target, player, data)
    if target == player and player:hasSkill(self, false, true) then
      if event == fk.Damaged then
        return data.from and not data.from.dead and not player.dead
      elseif event == fk.Death and player:getMark("joy__wuhun-turn") then
        return false
      else
        local availableTargets = {}
        local n = 0
        for _, p in ipairs(player.room.alive_players) do
          if p:getMark("@joy__nightmare") > n then
            availableTargets = {}
            table.insert(availableTargets, p.id)
            n = p:getMark("@joy__nightmare")
          elseif p:getMark("@joy__nightmare") == n and n ~= 0 then
            table.insert(availableTargets, p.id)
          end
        end
        if #availableTargets > 0 then
          self.cost_data = availableTargets
          return true
        end
      end
    end
    return false
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    if event == fk.Damaged then
      room:addPlayerMark(data.from, "@joy__nightmare", data.damage)
    else
      local p_id
      if #self.cost_data > 1 then
        p_id = room:askForChoosePlayers(player, self.cost_data, 1, 1, "#joy__wuhun-choose", self.name, false)[1]
      else
        p_id = self.cost_data[1]
      end
      local judge = {
        who = room:getPlayerById(p_id),
        reason = self.name,
        pattern = "peach,god_salvation|.",
      }
      room:judge(judge) 
      if event == fk.Death then
        player.room:setPlayerMark(player,"joy__wuhun-turn",1)
      end
      if judge.card.name == "peach" or judge.card.name == "god_salvation" then return false end
      local p = room:getPlayerById(p_id)
      room:loseHp(p,5,self.name)
    end
  end,
}
joy__wushen:addRelatedSkill(wushen_targetmod)
joy__wushen:addRelatedSkill(wushen_trigger)
godguanyu:addSkill(joy__wushen)
godguanyu:addSkill(wuhun)
Fk:loadTranslationTable {
  ["joy__godguanyu"] = "神关羽",
  ["#joy__godguanyu"] = "神鬼再临",

  ["joy__wushen"] = "武神",
  [":joy__wushen"] = "你的<font color='red'>♥</font>手牌可以当【杀】使用或打出；你使用<font color='red'>♥</font>【杀】无距离限制且伤害+1。",
  ["joy__wushen_trigger"] = "武神",
  ["joy__wuhun"] = "武魂",
  [":joy__wuhun"] = "锁定技，当你受到1点伤害后，伤害来源获得1枚“梦魇”；你脱离濒死状态或死亡时，令“梦魇”最多的一名其他角色判定，若不为【桃】或【桃园结义】，该角色流失5点体力。",
  ["@joy__nightmare"] = "梦魇",
  ["#joy__wuhun-choose"] = "武魂：选择一名“梦魇”最多的其他角色",
}

local godzhouyu = General(extension, "joy__godzhouyu", "god", 4)
local qinyin = fk.CreateTriggerSkill{
  name = "joy__qinyin",
  events = {fk.EventPhaseEnd},
  anim_type = "control",
  can_trigger = function(self, event, target, player, data)
    if target == player and player:hasSkill(self) and player.phase == Player.Discard then
      return #player.room.logic:getEventsOfScope(GameEvent.MoveCards, 1, function (e)
        for _, move in ipairs(e.data) do
          if move.from == player.id and move.moveReason == fk.ReasonDiscard then
            for _, info in ipairs(move.moveInfo) do
              if info.fromArea == Card.PlayerHand then
                return true
              end
            end
          end
        end
        return false
      end, Player.HistoryPhase) > 0
    end
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    local choices = {"loseHp", "joy__qinyin_alldraw"}
    if table.find(room.alive_players, function (p) return p:isWounded() end) then
      table.insert(choices, 1, "recover")
    end
    local choice = room:askForChoice(player, choices, self.name)
    for _, p in ipairs(room:getAlivePlayers()) do
      if not p.dead then
        if choice == "loseHp" then
          room:loseHp(p, 1, self.name)
        elseif choice == "joy__qinyin_alldraw" then
          p:drawCards(1, self.name)
        elseif p:isWounded() then
          room:recover{ who = p, num = 1, recoverBy = player, skillName = self.name }
        end
      end
    end
  end,
}
local yeyan = fk.CreateTriggerSkill{
  name = "joy__yeyan",
  anim_type = "offensive",
  events = {fk.EventPhaseStart},
  can_trigger = function(self, event, target, player, data)
    return target == player and player:hasSkill(self) and player.phase == Player.Play
  end,
  on_cost = function(self, event, target, player, data)
    local room = player.room
    local to = room:askForChoosePlayers(player, table.map(room:getOtherPlayers(player),  Util.IdMapper), 1, 1, "#joy__yeyan-choose", self.name, true)
    if #to > 0 then
      self.cost_data = to[1]
      return true
    end
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    room:damage({
      from = player,
      to = room:getPlayerById(self.cost_data),
      damage = 1,
      damageType = fk.FireDamage,
      skillName = self.name,
    })
  end,
}
godzhouyu:addSkill(qinyin)
godzhouyu:addSkill(yeyan)
Fk:loadTranslationTable{
  ["joy__godzhouyu"] = "神周瑜",
  ["#joy__godzhouyu"] = "赤壁的火神",

  ["joy__qinyin"] = "琴音",
  [":joy__qinyin"] = "弃牌阶段结束时，若你此阶段弃置过至少一张手牌，你可以选择：1. 令所有角色各回复1点体力；2. 令所有角色各失去1点体力。3.令所有角色各摸一张牌",
  ["joy__yeyan"] = "业炎",
  [":joy__yeyan"] = "出牌阶段开始时，你可以对一名其他角色造成1点火焰伤害。",
  ["#joy__yeyan-choose"] = "业炎：你可以对一名其他角色造成1点火焰伤害",

  ["joy__qinyin_alldraw"] = "各摸一张牌"
}

local godcaocao = General(extension, "joy__godcaocao", "god", 3)
local guixin = fk.CreateTriggerSkill{
  name = "joy__guixin",
  anim_type = "masochism",
  events = {fk.Damaged},
  on_trigger = function(self, event, target, player, data)
    self.cancel_cost = false
    for _ = 1, data.damage do
      if self.cancel_cost or not player:hasSkill(self) or
      table.every(player.room:getOtherPlayers(player), function (p) return p:isAllNude() end) then break end
      self:doCost(event, target, player, data)
    end
  end,
  on_cost = function(self, event, target, player, data)
    local room = player.room
    if room:askForSkillInvoke(player, self.name, data) then
      return true
    end
    self.cancel_cost = true
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    room:doIndicate(player.id, table.map(room.alive_players, Util.IdMapper))
    local choises = {"$Hand","$Equip","$Judge"}
    local choice = room:askForChoice(player,choises,self.name,"#joy__guixin-choose")
    local area = table.indexOf(choises, choice)
    local n = 0
    for _, p in ipairs(room:getOtherPlayers(player)) do
      if player.dead then break end
      local cards = p.player_cards[area]
      if #cards == 0 then cards = p:getCardIds("hej") end
      if #cards > 0 then
        n = n + 1
        room:obtainCard(player, table.random(cards), false, fk.ReasonPrey)
      end
    end
    if not player.dead and player.faceup and n > 4 then
      player:turnOver()
    end
  end,
}
godcaocao:addSkill(guixin)
godcaocao:addSkill("feiying")
Fk:loadTranslationTable{
  ["joy__godcaocao"] = "神曹操",
  ["#joy__godcaocao"] = "超世之英杰",

  ["joy__guixin"] = "归心",
  [":joy__guixin"] = "当你受到1点伤害后，你可随机获得所有其他角色区域中的一张牌（你选择优先获得牌的区域），如果获得牌大于4张且你为正面，你翻面。",
  ["#joy__guixin-choose"] = "归心:请选择优先获取的区域",
}

local godzhangjiao = General(extension, "joy__godzhangjiao", "god", 3)
local yizhao = fk.CreateTriggerSkill{
  name = "joy__yizhao",
  anim_type = "drawcard",
  frequency = Skill.Compulsory,
  events = {fk.CardUsing, fk.CardResponding},
  can_trigger = function(self, event, target, player, data)
    return target == player and player:hasSkill(self) and data.card.number > 0
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    local n1 = tostring(player:getMark("@joy__zhangjiao_huang"))
    room:addPlayerMark(player, "@joy__zhangjiao_huang", math.min(data.card.number, #Fk:getAllCardIds() - player:getMark("@joy__zhangjiao_huang")))
    local n2 = tostring(player:getMark("@joy__zhangjiao_huang"))
    if n1//10 == n2//10 then 
      return
    end
    local x = (n2%10)//10
    if x == 0 then x = 10 end  --yes, tenyear is so strange
    local card = room:getCardsFromPileByRule(".|"..x)
    if #card > 0 then
      room:moveCards({
        ids = card,
        to = player.id,
        toArea = Card.PlayerHand,
        moveReason = fk.ReasonJustMove,
        proposer = player.id,
        skillName = self.name,
      })
    end
  end,

  refresh_events = {fk.EventLoseSkill},
  can_refresh = function(self, event, target, player, data)
    return player == target and data == self and player:getMark("@joy__zhangjiao_huang") ~= 0
  end,
  on_refresh = function(self, event, target, player, data)
    player.room:setPlayerMark(player, "@joy__zhangjiao_huang", 0)
  end,
}
local sanshou = fk.CreateTriggerSkill{
  name = "joy__sanshou",
  anim_type = "defensive",
  events = {fk.DamageInflicted},
  can_trigger = function(self, event, target, player, data)
    return target == player and player:hasSkill(self)
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    local cards = room:getNCards(3)
    room:moveCards({
      ids = cards,
      toArea = Card.Processing,
      moveReason = fk.ReasonJustMove,
      skillName = self.name,
    })
    local yes = false
    for _, id in ipairs(cards) do
      if player:getMark("joy__sanshou_"..Fk:getCardById(id):getTypeString().."-turn") == 0 then
        room:setCardEmotion(id, "judgegood")
        yes = true
      else
        room:setCardEmotion(id, "judgebad")
      end
    end
    room:delay(1000)
    room:moveCards({
      ids = cards,
      fromArea = Card.Processing,
      toArea = Card.DiscardPile,
      moveReason = fk.ReasonJustMove,
      skillName = self.name,
    })
    if yes then
      return true
    end
  end,

  refresh_events = {fk.AfterCardUseDeclared},
  can_refresh = function(self, event, target, player, data)
    return player:hasSkill(self, true)
  end,
  on_refresh = function(self, event, target, player, data)
    player.room:addPlayerMark(player, "joy__sanshou_"..data.card:getTypeString().."-turn", 1)
  end,
}
local sijun = fk.CreateTriggerSkill{
  name = "joy__sijun",
  anim_type = "drawcard",
  events = {fk.EventPhaseStart},
  can_trigger = function(self, event, target, player, data)
    return target == player and player:hasSkill(self) and player.phase == Player.Start and
    player:getMark("@joy__zhangjiao_huang") > #player.room.draw_pile
  end,
  on_use = function(self, event, tar, player, data)
    local room = player.room
    room:setPlayerMark(player, "@joy__zhangjiao_huang", 0)
    room:shuffleDrawPile()
    local cards = {}
    if #room.draw_pile > 3 then
      local ret = {}
      local total = 36
      local numnums = {}
      local maxs = {}
      local pileToSearch = {}
      for i = 1, 13, 1 do
        table.insert(numnums, 0)
        table.insert(maxs, 36//i)
        table.insert(pileToSearch, {})
      end
      for _, id in ipairs(room.draw_pile) do
        local x = Fk:getCardById(id).number
        if x > 0 and x < 14 then
          table.insert(pileToSearch[x], id)
          if numnums[x] < maxs[x] then
            numnums[x] = numnums[x] + 1
          end
        end
      end
      local nums = {}
      for index, value in ipairs(numnums) do
        for _ = 1, value, 1 do
          table.insert(nums, index)
        end
      end
      local postsum = {}
      local nn = #nums
      postsum[nn+1] = 0
      for i = nn, 1, -1 do
        postsum[i] = postsum[i+1] + nums[i]
      end
      local function nSum(n, l, r, target)
        local _ret = {}
        if n == 1 then
          for i = l, r, 1 do
            if nums[i] == target then
              table.insert(_ret, {target})
              break
            end
          end
        elseif n == 2 then
          while l < r do
            local now = nums[l] + nums[r]
            if now > target then
              r = r - 1
            elseif now < target then
              l = l + 1
            else
              table.insert(_ret, {nums[l], nums[r]})
              l = l + 1
              r = r - 1
              while l < r and nums[l] == nums[l-1] do
                l = l + 1
              end
              while l < r and nums[r] == nums[r+1] do
                r = r - 1
              end
            end
          end
        else
          for i = l, r-(n-1), 1 do
            if (i > l and nums[i] == nums[i-1]) or
              (nums[i] + postsum[r - (n-1) + 1] < target) then
            else
              if postsum[i] - postsum[i+n] > target then
                break
              end
              local v = nSum(n-1, i+1, r, target - nums[i])
              for j = 1, #v, 1 do
                table.insert(v[j], nums[i])
                table.insert(_ret, v[j])
              end
            end
          end
        end
        return _ret
      end
      for i = 3, total, 1 do
        table.insertTable(ret, nSum(i, 1, #nums, total))
      end
      if #ret > 0 then
        local compare = table.random(ret)
        table.sort(compare)
        local x = 0
        local current_n = compare[1]
        for _, value in ipairs(compare) do
          if value == current_n then
            x = x + 1
          else
            table.insertTable(cards, table.random(pileToSearch[current_n], x))
            x = 1
            current_n = value
          end
        end
        table.insertTable(cards, table.random(pileToSearch[current_n], x))
      end
    end
    if #cards == 0 then
      local tmp_drawPile = table.simpleClone(room.draw_pile)
      local sum = 0
      while sum < 36 and #tmp_drawPile > 0 do
        local id = table.remove(tmp_drawPile, math.random(1, #tmp_drawPile))
        sum = sum + Fk:getCardById(id).number
        table.insert(cards, id)
      end
    end
    if #cards > 0 then
      room:moveCards({
        ids = cards,
        to = player.id,
        toArea = Card.PlayerHand,
        moveReason = fk.ReasonJustMove,
        proposer = player.id,
        skillName = self.name,
      })
    end
  end,
}
local tianjie = fk.CreateTriggerSkill{
  name = "joy__tianjie",
  anim_type = "offensive",
  events = {fk.TurnEnd},
  can_trigger = function(self, event, target, player, data)
    if player:hasSkill(self) then
      if player:getMark(self.name) > 0 then
        player.room:setPlayerMark(player, self.name, 0)
        return true
      end
    end
  end,
  on_cost = function(self, event, target, player, data)
    local room = player.room
    local tos = room:askForChoosePlayers(player, table.map(room:getOtherPlayers(player, false), Util.IdMapper), 1, 3, "#joy__tianjie-choose", self.name, true)
    if #tos > 0 then
      self.cost_data = tos
      return true
    end
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    for _, id in ipairs(self.cost_data) do
      local p = room:getPlayerById(id)
      local n = math.max(1, #table.filter(p.player_cards[Player.Hand], function(c) return Fk:getCardById(c).name == "jink" end))
      room:damage{
        from = player,
        to = p,
        damage = n,
        damageType = fk.ThunderDamage,
        skillName = self.name,
      }
    end
  end,

  refresh_events = {fk.AfterDrawPileShuffle},
  can_refresh = function(self, event, target, player, data)
    return player:hasSkill(self, true)
  end,
  on_refresh = function(self, event, target, player, data)
    player.room:addPlayerMark(player, self.name, 1)
  end,
}
godzhangjiao:addSkill(yizhao)
godzhangjiao:addSkill(sanshou)
godzhangjiao:addSkill(sijun)
godzhangjiao:addSkill(tianjie)
Fk:loadTranslationTable{
  ["joy__godzhangjiao"] = "神张角",
  ["#joy__godzhangjiao"] = "末世的起首",

  ["joy__yizhao"] = "异兆",
  [":joy__yizhao"] = "锁定技，当你使用或打出一张牌后，获得等同于此牌点数的“黄”标记，然后若“黄”标记数的十位数变化，你随机获得牌堆中一张点数为变化后十位数的牌。（“黄”标记不会大于游戏牌数。）",
  ["joy__sanshou"] = "三首",
  [":joy__sanshou"] = "当你受到伤害时，你可以亮出牌堆顶的三张牌，若其中有本回合所有角色均未使用过的牌的类型，防止此伤害。",
  ["joy__sijun"] = "肆军",
  [":joy__sijun"] = "准备阶段，若“黄”标记数大于牌堆里的牌数，你可以移去所有“黄”标记并洗牌，然后获得随机张点数之和为36的牌。",
  ["joy__tianjie"] = "天劫",
  [":joy__tianjie"] = "一名角色的回合结束时，若本回合牌堆进行过洗牌，你可以对至多三名其他角色各造成X点雷电伤害（X为其手牌中【闪】的数量且至少为1）。",
  ["@joy__zhangjiao_huang"] = "黄",
  ["#joy__tianjie-choose"] = "天劫：你可以对至多三名其他角色各造成X点雷电伤害（X为其手牌中【闪】数，至少为1）",

  ["$joy__yizhao1"] = "苍天已死，此黄天当立之时。",
  ["$joy__yizhao2"] = "甲子尚水，显炎汉将亡之兆。",
  ["$joy__sanshou1"] = "三公既现，领大道而立黄天。",
  ["$joy__sanshou2"] = "天地三才，载厚德以驱魍魉。",
  ["$joy__sijun1"] = "联九州黎庶，撼一家之王庭。",
  ["$joy__sijun2"] = "吾以此身为药，欲医天下之疾。",
  ["$joy__tianjie1"] = "苍天既死，贫道当替天行道。",
  ["$joy__tianjie2"] = "贫道张角，请大汉赴死！",
  ["~joy__godzhangjiao"] = "诸君唤我为贼，然我所窃何物？",
}

local godTaishici = General(extension, "joy__godtaishici", "god", 4)
Fk:loadTranslationTable{
  ["joy__godtaishici"] = "神太史慈",

}

local dulie = fk.CreateTriggerSkill{
  name = "joy__dulie",
  events = {fk.TargetConfirming,fk.EnterDying},
  anim_type = "defensive",
  frequency = Skill.Compulsory,
  can_trigger = function(self, event, target, player, data)
    local id = {}
      for _, p in ipairs(player.room:getAlivePlayers()) do
        if p:getMark("@@joy__powei_wei") > 0 then
          table.insert(id,p)
        end
      end
    if event == fk.EnterDying and player:hasSkill(self) and target == player and #id > 0 then
      local dying_id = target:getMark(self.name)
      local cur_event = player.room.logic:getCurrentEvent()
      if dying_id ~= 0 then
        return cur_event.id == dying_id
      else
        local events = player.room.logic.event_recorder[GameEvent.Dying] or Util.DummyTable
        local canInvoke = true
        for i = #events, 1, -1 do
          local e = events[i]
          if e.data[1].who == target.id and e.id ~= cur_event.id then
            canInvoke = false
            break
          end
        end
        if canInvoke then
          player.room:setPlayerMark(target, self.name, cur_event.id)
          return target == player and player.hp < 1 
        end
      end
    elseif event == fk.TargetConfirming and target == player then
      return target == player and player:hasSkill(self) and data.card.trueName == "slash"
    end
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    if target == player and player.hp < 1 then
      room:notifySkillInvoked(player, self.name, "negative")
      local id = {}
      for _, p in ipairs(room:getAlivePlayers()) do
        if p:getMark("@@joy__powei_wei") > 0 then
          table.insert(id,p)
        end
      end
      if #id > 0 then
        if player.hp < 1 then
          room:recover({
            who = player,
            num = #id - player.hp,
            recoverBy = player,
            skillName = self.name,
          })
        end
      end
    else
      local judge = {
        who = player,
        reason = self.name,
        pattern = ".|.|heart",
      }

      room:judge(judge)
      if judge.card.suit == Card.Heart then
        AimGroup:cancelTarget(data, player.id)
        return true
     end
    end
  end,
}
Fk:loadTranslationTable{
  ["joy__dulie"] = "笃烈",
  [":joy__dulie"] = "锁定技，当你成为其他角色使用【杀】的目标时，你判定，若结果为<font color='red'>♥</font>，取消之。"..
  "你首次进入濒死状态时，若场上存在“围”标记，你将体力回复至X点（X为场上“围”标记数）",

  ["$joy__dulie1"] = " ",
  ["$joy__dulie2"] = " ",

}

godTaishici:addSkill(dulie)

local chongwei = fk.CreateTriggerSkill{
  name = "joy__chongwei",
  events = {fk.GameStart, fk.TurnStart, fk.Damaged,fk.RoundEnd},
  mute = true,
  can_trigger = function(self, event, target, player, data)
    local id = {}
      for _, p in ipairs(player.room:getAlivePlayers()) do
        if p:getMark("@@joy__powei_wei") > 0 then
          table.insert(id,p)
        end
      end
    if  not player:hasSkill(self) or (#id == 0 and event ~= fk.GameStart) then
      return false
    end
    if event == fk.GameStart then
      return true
    elseif event == fk.TurnStart then
      return target == player or target:getMark("@@joy__powei_wei") > 0
    elseif event == fk.Damaged then
      return target:getMark("@@joy__powei_wei") > 0
    else
      return true
    end
  end,
  on_cost = function(self, event, target, player, data)
    self.cost_data = nil
    if event == fk.TurnStart and target:getMark("@@joy__powei_wei") > 0 then
      local room = player.room

      local choices = { "Cancel" }
      if target.hp <= player.hp and target ~= player and target:getHandcardNum() > 0 then
        table.insert(choices, 1, "joy__powei_prey")
      end
      if table.find(player:getCardIds(Player.Hand), function(id)
        return not player:prohibitDiscard(Fk:getCardById(id))
      end) then
        table.insert(choices, 1, "joy__powei_damage")
      end

      if #choices == 1 then
        return false
      end

      local choice = room:askForChoice(player, choices, self.name)
      if choice == "Cancel" then
        return false
      end

      if choice == "joy__powei_damage" then
        local cardIds = room:askForDiscard(player, 1, 1, false, self.name, true, nil, "#joy__powei-damage::" .. target.id, true)
        if #cardIds == 0 then
          return false
        end

        self.cost_data = cardIds[1]
      else
        self.cost_data = choice
      end
    end

    return true
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    if event == fk.GameStart then
      room:notifySkillInvoked(player, self.name)
      player:broadcastSkillInvoke(self.name, 1)
      for _, p in ipairs(room:getOtherPlayers(player)) do
        room:setPlayerMark(p, "@@joy__powei_wei", 1)
      end
      local id = {}
      for _, p in ipairs(room:getAlivePlayers()) do
        if p:getMark("@@joy__powei_wei") > 0 then
          table.insert(id,p)
        end
      end
      room:setPlayerMark(player, "joy__poweilose", #id)
    elseif event == fk.TurnStart then
      if target == player then
        if table.find(room.alive_players, function(p)
          return p:getMark("@@joy__powei_wei") > 0
        end) then
          room:notifySkillInvoked(player, self.name)
          player:broadcastSkillInvoke(self.name, 1)
          local hasLastPlayer = false
          for _, p in ipairs(room:getAlivePlayers()) do
            if p:getMark("@@joy__powei_wei") > (hasLastPlayer and 1 or 0) and not (#room.alive_players < 3 and p:getNextAlive() == player) then
              hasLastPlayer = true
              room:removePlayerMark(p, "@@joy__powei_wei")
              local nextPlayer = p:getNextAlive()
              if nextPlayer == player then
                nextPlayer = player:getNextAlive()
              end

              room:addPlayerMark(nextPlayer, "@@joy__powei_wei")
            else
              hasLastPlayer = false
            end
          end
        end
      end

      if type(self.cost_data) == "number" then
        room:notifySkillInvoked(player, self.name, "offensive")
        player:broadcastSkillInvoke(self.name, 1)
        room:throwCard({ self.cost_data }, self.name, player, player)
        room:damage({
          from = player,
          to = target,
          damage = 1,
          damageType = fk.NormalDamage,
          skillName = self.name,
        })

        room:setPlayerMark(player, "joy__powei_debuff-turn", target.id)
      elseif self.cost_data == "joy__powei_prey" then
        room:notifySkillInvoked(player, self.name, "control")
        player:broadcastSkillInvoke(self.name, 1)
        local cardId = room:askForCardChosen(player, target, "h", self.name)
        room:obtainCard(player, cardId, false, fk.ReasonPrey)
        room:setPlayerMark(player, "joy__powei_debuff-turn", target.id)
      end
    elseif event == fk.Damaged then
      room:setPlayerMark(target, "@@joy__powei_wei", 0)
    elseif event == fk.RoundEnd then
      local id = {}
      for _, p in ipairs(room:getAlivePlayers()) do
        if p:getMark("@@joy__powei_wei") > 0 then
          table.insert(id,p)
        end
      end
      room:setPlayerMark(player, "joy__poweilose", #id)
    end
  end,
}
Fk:loadTranslationTable{
  ["joy__chongwei"] = "重围",
  [":joy__chongwei"] = "游戏开始时，你令所有其他角色获得“围”标记；回合开始时，你令所有拥有“围”标记的角色将“围”标记移动至下家"..
  "（若你获得“围”标记，则直接移动至你的下家）；有“围”标记的角色受到伤害后，移去其“围”标记；有“围”的角色的回合开始时，你可以选择一项并令"..
  "你于本回合内视为处于其攻击范围内：1.弃置一张手牌，对其造成1点伤害；2.若其体力值不大于你，你获得其一张手牌。",
  ["@@joy__powei_wei"] = "围",
  ["joy__powei_damage"] = "弃一张手牌对其造成1点伤害",
  ["joy__powei_prey"] = "获得其1张手牌",
  ["#joy__powei-damage"] = "破围：你可以弃置一张手牌，对 %dest 造成1点伤害",

  ["$joy__chongwei1"] = " ",
  ["$joy__chongwei2"] = " ",
}

local chongweiDebuff = fk.CreateAttackRangeSkill{  --FIXME!!!
  name = "#joy__chongwei-debuff",
  within_func = function (self, from, to)
    return to:getMark("joy__chongwei_debuff-turn") == from.id
  end,
}

chongwei:addRelatedSkill(chongweiDebuff)
godTaishici:addSkill(chongwei)

local powei = fk.CreateTriggerSkill{
  name = "joy__powei",
  frequency = Skill.Wake,
  events = {fk.TurnEnd},
  can_trigger = function(self, event, target, player, data)
    return player:hasSkill(self) and player:usedSkillTimes(self.name, Player.HistoryGame) == 0
  end,
  can_wake = function(self, event, target, player, data)
    return not table.find(player.room.alive_players, function(p)
      return p:getMark("@@joy__powei_wei") > 0
    end) 
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    room:handleAddLoseSkills(player, "joy__shenzhuo", nil, true, false)
    local n = player.getMark(player,"joy__poweilose")
    local id = {}
      for _, p in ipairs(room:getAlivePlayers()) do
        if p:getMark("@@joy__powei_wei") > 0 then
          table.insert(id,p)
        end
      end
    if not player.dead then
      room:drawCards(player,n-#id,self.name)
    end
  end,
}

godTaishici:addSkill(powei)

Fk:loadTranslationTable{

["joy__powei"] = "破围",
[":joy__powei"] = "觉醒技，每个回合结束时，若场上没有“围”标记，你获得技能“神著”并摸X张牌（X为本轮移除的“围”标记)",

["$joy__powei1"] = " ",
["$joy__powei2"] = " ",
}
local shenzhuo = fk.CreateTriggerSkill{
  name = "joy__shenzhuo",
  events = {fk.TurnStart,fk.CardUseFinished},
  anim_type = "drawcard",
  frequency = Skill.Compulsory,
  can_trigger = function(self, event, target, player, data)
    return
      (event == fk.TurnStart and target == player and player:hasSkill(self.name)) or
      (target == player and
      player:hasSkill(self) and
      data.card.trueName == "slash" and
      not data.card:isVirtual())
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    if event == fk.TurnStart and player:hasSkill(self.name) then
      room:notifySkillInvoked(player, "joy__shenzhuo", "drawcard")
      local ids = room:getCardsFromPileByRule("slash|.|.", 1, "DrawPile")
      if #ids > 0 then
        room:obtainCard(player, ids[1], false, fk.ReasonPrey)
      end
    else
      local choice = room:askForChoice(player, { "joy__shenzhuo_drawOne", "joy__shenzhuo_drawThree" }, self.name)
      if choice == "joy__shenzhuo_drawOne" then
        player:drawCards(1, self.name)
        room:addPlayerMark(player, "joy__shenzhuo-turn")
      else
        player:drawCards(3, self.name)
        room:setPlayerMark(player, "@joy__shenzhuo_debuff-turn", "joy__shenzhuo_debuff")
     end
    end
  end,
}
Fk:loadTranslationTable{
  ["joy__shenzhuo"] = "神著",
  [":joy__shenzhuo"] = "锁定技，回合开始时摸一张【杀】，"..
  "当你使用非转化且非虚拟的【杀】结算结束后，你须选择一项：1.摸一张牌，令你于本回合内使用【杀】的次数上限+1；"..
  "2.摸三张牌，令你于本回合内不能使用【杀】。",
  ["joy__shenzhuo_drawOne"] = "摸1张牌，可以继续出杀",
  ["joy__shenzhuo_drawThree"] = "摸3张牌，本回合不能出杀",
  ["@joy__shenzhuo_debuff-turn"] = "神著",
  ["joy__shenzhuo_debuff"] = "不能出杀",

  ["$joy__shenzhuo1"] = " ",
  ["$joy__shenzhuo2"] = " ",
}

local shenzhuoBuff = fk.CreateTargetModSkill{
  name = "#joy__shenzhuo-buff",
  residue_func = function(self, player, skill, scope)
    if skill.trueName == "slash_skill" and scope == Player.HistoryPhase then
      return player:getMark("joy__shenzhuo-turn")
    end
  end,
}

local shenzhuoDebuff = fk.CreateProhibitSkill{
  name = "#joy__shenzhuo_prohibit",
  prohibit_use = function(self, player, card)
    return player:getMark("@joy__shenzhuo_debuff-turn") ~= 0 and card.trueName == "slash"
  end,
}

shenzhuo:addRelatedSkill(shenzhuoBuff)
shenzhuo:addRelatedSkill(shenzhuoDebuff)
godTaishici:addRelatedSkill(shenzhuo)

local godlvbu = General(extension, "joy__godlvbu", "god", 6)
local wuqian = fk.CreateTriggerSkill{
  name = "joy__wuqian",
  events = {fk.TargetSpecified},
  frequency = Skill.Compulsory,
  can_trigger = function(self, event, target, player, data)
    if data.card.trueName == "slash" then
      return target == player and player:hasSkill(self) and  player:usedCardTimes("slash") <= 1 and data.firstTarget
    elseif  data.card.trueName == "duel" then
      return target == player and player:hasSkill(self) and player:usedCardTimes("duel") <= 1 and data.firstTarget
    end
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    local card_event = room.logic:getCurrentEvent():findParent(GameEvent.UseCard)
      card_event.joy__wuqian_armor = true
      room:addPlayerMark(room:getPlayerById(data.to), fk.MarkArmorNullified)
      if not player:hasSkill("wushuang") then
        room:handleAddLoseSkills(player, "wushuang", nil, true, false)
        room:addPlayerMark(player, "wuqian_wushuang")
      end
  end,

  refresh_events = {fk.CardUseFinished},
  can_refresh = function(self, event, target, player, data)
    if player ~= target then return false end
    local card_event = player.room.logic:getCurrentEvent():findParent(GameEvent.UseCard, true)
    return card_event and card_event.joy__wuqian_armor
  end,
  on_refresh = function(self, event, target, player, data)
    local room = player.room
    for _, p in ipairs(room.alive_players) do
      room:removePlayerMark(p, fk.MarkArmorNullified, num)
    end
    if player:getMark("wuqian_wushuang") == 1 then
        room:handleAddLoseSkills(player, "-wushuang", nil, true, false)
        room:removePlayerMark(player,"wuqian_wushuang")
    end
  end,
}
local shenfen = fk.CreateActiveSkill{
  name = "joy__shenfen",
  anim_type = "offensive",
  frequency = Skill.Limited,
  can_use = function(self, player)
    return player:usedSkillTimes(self.name, Player.HistoryGame) == 0
  end,
  card_num = 0,
  target_num = 0,
  card_filter = Util.FalseFunc,
  on_use = function(self, room, effect)
    local player = room:getPlayerById(effect.from)
    room:loseHp(player,3,self.name)
    local targets = room:getOtherPlayers(player, true)
    room:doIndicate(effect.from, table.map(targets, Util.IdMapper))
    table.forEach(targets, function(p)
      if not p.dead then room:damage{ from = player, to = p, damage = 1, skillName = self.name } end
    end)
    table.forEach(targets, function(p)
      if not p.dead then p:throwAllCards("e") end
    end)
    table.forEach(targets, function(p)
      if not p.dead then
        room:askForDiscard(p, 4, 4, false, self.name, false)
      end
    end)
  end
}
godlvbu:addSkill(wuqian)
godlvbu:addSkill(shenfen)
godlvbu:addRelatedSkill("wushuang")
Fk:loadTranslationTable{
  ["joy__godlvbu"] = "神吕布",
  ["#joy__godlvbu"] = "修罗之道",

  ["joy__wuqian"] = "无前",
  [":joy__wuqian"] = "锁定技，每个自己回合使用的第一张【杀】和【决斗】，获得“无双”效果且无视目标角色的防具。",
  ["joy__shenfen"] = "神愤",
  [":joy__shenfen"] = "限定技，你可以失去3点体力然后对所有其他角色各造成1点伤害，然后这些角色各弃置其装备区里的所有牌，各弃置四张手牌。",


}

local godmachao = General(extension, "joy__godmachao", "god", 4)
local shouli = fk.CreateViewAsSkill{
  name = "joy__shouli",
  pattern = "slash,jink",
  prompt = "#joy__shouli-active",
  interaction = function(self,player)
    local names = {}
    local pat = Fk.currentResponsePattern
    if pat == nil and table.find(Fk:currentRoom().alive_players, function(p)
      return p:getEquipment(Card.SubtypeOffensiveRide) ~= nil end) then
      local slash = Fk:cloneCard("slash")
      slash.skillName = "shouli"
      if Self:canUse(slash) and not Self:prohibitUse(slash) then
        table.insert(names, "slash")
      end
    else
      if Exppattern:Parse(pat):matchExp("slash") and table.find(Fk:currentRoom().alive_players, function(p)
        return p:getEquipment(Card.SubtypeOffensiveRide) ~= nil end) then
          table.insert(names, "slash")
      end
      if Exppattern:Parse(pat):matchExp("jink") and table.find(Fk:currentRoom().alive_players, function(p)
        return p:getEquipment(Card.SubtypeDefensiveRide) ~= nil end) then
          table.insert(names, "jink")
      end
    end
    if #names == 0 then return end
    return UI.ComboBox {choices = names}  --FIXME: 体验很不好！
  end,
  view_as = function(self, cards)
    if self.interaction.data == nil then return end
    local card = Fk:cloneCard(self.interaction.data)
    card.skillName = self.name
    return card
  end,
  before_use = function(self, player, use)
    local room = player.room
    local horse_type = use.card.trueName == "slash" and Card.SubtypeOffensiveRide or Card.SubtypeDefensiveRide
    local horse_name = use.card.trueName == "slash" and "offensive_horse" or "defensive_horse"
    local targets = table.filter(room.alive_players, function (p)
      return p:getEquipment(horse_type) ~= nil
    end)
    if #targets > 0 then
      local tos = room:askForChoosePlayers(player, table.map(targets, Util.IdMapper), 1, 1, "#joy__shouli-horse:::" .. horse_name, self.name, false, true)
      if #tos > 0 then
        local to = room:getPlayerById(tos[1])
        room:addPlayerMark(to, "@@joy__shouli-turn")
        if to ~= player then
          room:addPlayerMark(player, "@@joy__shouli-turn")
          room:addPlayerMark(to, MarkEnum.UncompulsoryInvalidity .. "-turn")
        end
        local horse = to:getEquipment(horse_type)
        if horse then
          room:obtainCard(player.id, horse, false, fk.ReasonPrey)
          if room:getCardOwner(horse) == player and room:getCardArea(horse) == Player.Hand then
            use.card:addSubcard(horse)
            use.extraUse = true
            return
          end
        end
      end
    end
    return ""
  end,
  enabled_at_play = function(self, player)
    return table.find(Fk:currentRoom().alive_players, function(p)
      return p:getEquipment(Card.SubtypeOffensiveRide) ~= nil end)
  end,
  enabled_at_response = function(self, player)
    local pat = Fk.currentResponsePattern
    return pat and table.find(Fk:currentRoom().alive_players, function(p)
      return (Exppattern:Parse(pat):matchExp("slash") and p:getEquipment(Card.SubtypeOffensiveRide) ~= nil) or
        (Exppattern:Parse(pat):matchExp("jink") and p:getEquipment(Card.SubtypeDefensiveRide) ~= nil)
    end)
  end,
}
local shouli_trigger = fk.CreateTriggerSkill{
  name = "#joy__shouli_trigger",
  events = {fk.GameStart},
  mute = true,
  main_skill = shouli,
  can_trigger = function(self, event, target, player, data)
    return player:hasSkill(shouli)
  end,
  on_cost = Util.TrueFunc,
  on_use = function(self, event, target, player, data)
    local room = player.room
    player:broadcastSkillInvoke(shouli.name)
    room:notifySkillInvoked(player, shouli.name)
    local temp = player.next
    local players = {}
    while temp ~= player do
      if not temp.dead then
        table.insert(players, temp)
      end
      temp = temp.next
    end
    table.insert(players, player)
    room:doIndicate(player.id, table.map(players, Util.IdMapper))
    for _, p in ipairs(players) do
      if not p.dead then
        local cards = {}
        for i = 1, #room.draw_pile, 1 do
          local card = Fk:getCardById(room.draw_pile[i])
          if (card.sub_type == Card.SubtypeOffensiveRide or card.sub_type == Card.SubtypeDefensiveRide) and
          p:canUse(card) and not p:prohibitUse(card) then
            table.insertIfNeed(cards, card)
          end
        end
        if #cards > 0 then
          local horse = cards[math.random(1, #cards)]
          room:useCard{
            from = p.id,
            card = horse,
          }
        end
      end
    end
  end,
}
local shouli_delay = fk.CreateTriggerSkill{
  name = "#joy__shouli_delay",
  events = {fk.DamageInflicted},
  mute = true,
  can_trigger = function(self, event, target, player, data)
    return target == player and player:getMark("@@joy__shouli-turn") > 0
  end,
  on_cost = Util.TrueFunc,
  on_use = function(self, event, target, player, data)
    data.damage = data.damage + 1
    data.damageType = fk.ThunderDamage
  end,
}
local shouli_targetmod = fk.CreateTargetModSkill{
  name = "#joy__shouli_targetmod",
  bypass_times = function(self, player, skill, scope, card)
    return card and scope == Player.HistoryPhase and table.contains(card.skillNames, shouli.name)
  end,
}
shouli:addRelatedSkill(shouli_trigger)
shouli:addRelatedSkill(shouli_delay)
shouli:addRelatedSkill(shouli_targetmod)
local hengwu = fk.CreateTriggerSkill{
  name = "joy__hengwu",
  anim_type = "drawcard",
  events = {fk.CardUsing, fk.CardResponding},
  can_trigger = function(self, event, target, player, data)
    if target == player and player:hasSkill(self) then
      local suit = data.card.suit
      return table.every(player.player_cards[Player.Hand], function (id)
        return Fk:getCardById(id).suit ~= suit end) and table.find(player.room.alive_players, function (p)
          return table.find(p.player_cards[Player.Equip], function (id)
            return Fk:getCardById(id).suit == suit end) end)
    end
  end,
  on_use = function(self, event, target, player, data)
    local x = 0
    local suit = data.card.suit
    for _, p in ipairs(player.room.alive_players) do
      for _, id in ipairs(p.player_cards[Player.Equip]) do
        if Fk:getCardById(id).suit == suit then
          x = x + 1
        end
      end
    end
    if x > 0 then
      player:drawCards(x, self.name)
    end
  end,
}
godmachao:addSkill("shouli")
godmachao:addSkill(hengwu)
Fk:loadTranslationTable{
  ["joy__godmachao"] = "神马超",
  ["#joy__godmachao"] = "神威天将军",

  ["joy__shouli"] = "狩骊",
  [":joy__shouli"] = "游戏开始时，从下家开始所有角色随机使用牌堆中的一张坐骑。你可以将场上的一张进攻马当【杀】（不计入限制的次数且无次数限制）、"..
  "防御马当【闪】使用或打出，以此法失去坐骑的其他角色本回合非锁定技失效，你与其本回合受到的伤害+1且改为雷电伤害。",
  ["joy__hengwu"] = "横骛",
  [":joy__hengwu"] = "当你使用或打出牌时，若你没有该花色的手牌，你可以摸X张牌（X为场上与此牌花色相同的装备数量）。",

  ["#joy__shouli-active"] = "发动狩骊，将场上的一张进攻马当【杀】、防御马当【闪】使用或打出",
  ["@@joy__shouli-turn"] = "狩骊",
  ["#joy__shouli-horse"] = "狩骊：选择一名装备着 %arg 的角色",
  ["#joy__shouli_trigger"] = "狩骊",
  ["#joy__shouli_delay"] = "狩骊",

  ["$joy__shouli1"] = "敢缚苍龙擒猛虎，一枪纵横定天山！",
  ["$joy__shouli2"] = "马踏祁连山河动，兵起玄黄奈何天！",
  ["$joy__hengwu1"] = "雷部显圣，引赤电为翼，铸霹雳成枪！",
  ["$joy__hengwu2"] = "一骑破霄汉，饮马星河，醉卧广寒！",
  ["~joy__godmachao"] = "七情难掩，六欲难消，何谓之神？",

}

local godjiangwei = General(extension, "joy__godjiangwei", "god", 4)
godjiangwei:addSkill("tianren")
godjiangwei:addSkill("jiufa")
godjiangwei:addSkill("pingxiang")
Fk:loadTranslationTable{
  ["joy__godjiangwei"] = "神姜维",
  ["#joy__godjiangwei"] = "怒麟布武",

}

local godzhangfei = General(extension, "joy__godzhangfei", "god", 4)
local xunshi = fk.CreateFilterSkill{
  name = "joy__xunshi",
  mute = true,
  frequency = Skill.Compulsory,
  card_filter = function(self, card, player)
    return player:hasSkill(self) and card.multiple_targets 
  end,
  view_as = function(self, card)
    return Fk:cloneCard("slash", Card.NoSuit, card.number)
  end,
}
local xunshi_trigger = fk.CreateTriggerSkill{
  name = "#joy__xunshi_trigger",
  anim_type = "offensive",
  frequency = Skill.Compulsory,
  events = {fk.CardUsing},
  mute = true,
  can_trigger = function(self, event, target, player, data)
    return target == player and player:hasSkill(xunshi) and data.card.color == Card.NoColor
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    room:notifySkillInvoked(player, xunshi.name)
    player:broadcastSkillInvoke(xunshi.name)
    if player:getMark("xunshi") < 4 then
      player.room:addPlayerMark(player, "xunshi", 1)
    end
    local targets = player.room:getUseExtraTargets( data)
    local n = #targets
    if n == 0 then return false end
    local tos = room:askForChoosePlayers(player, targets, 1, n, "#xunshi-choose:::"..data.card:toLogString(), xunshi.name, true)
    if #tos > 0 then
      table.forEach(tos, function (id)
        table.insert(data.tos, {id})
      end)
    end
  end,
}
local xunshi_targetmod = fk.CreateTargetModSkill{
  name = "#joy__xunshi_targetmod",
  bypass_times = function(self, player, skill, scope, card)
    return player:hasSkill(xunshi) and card and card.color == Card.NoColor
  end,
  bypass_distances =  function(self, player, skill, card)
    return player:hasSkill(xunshi) and card and card.color == Card.NoColor
  end,
}
xunshi:addRelatedSkill(xunshi_trigger)
xunshi:addRelatedSkill(xunshi_targetmod)
godzhangfei:addSkill("shencai")
godzhangfei:addSkill(xunshi)
Fk:loadTranslationTable{
  ["joy__godzhangfei"] = "神张飞",
  ["#joy__godzhangfei"] = "两界大巡环使",
  ["joy__xunshi"] = "巡使",
  ["#joy__xunshi_trigger"] = "巡使",
  [":joy__xunshi"] = "锁定技，你的多目标锦囊牌均视为无色【杀】。你使用无色牌无距离和次数限制且可以额外指定任意个目标，然后〖神裁〗的发动次数+1（至多为5）。",

  ["$shencai_joy__godzhangfei1"] = " ",
  ["$shencai_joy__godzhangfei2"] = " ",
  ["$joy__xunshi1"] = " ",
  ["$joy__xunshi2"] = " ",
  ["~joy__godzhangfei"] = " ",
}

local godxunyu = General(extension, "joy__godxunyu", "god", 3)
local godxunyu_win = fk.CreateActiveSkill{ name = "joy__godxunyu_win_audio" }
godxunyu_win.package = extension
Fk:addSkill(godxunyu_win)

local tianzuo = fk.CreateTriggerSkill{
  name = "joy__tianzuo",
  anim_type = "defensive",
  events = {fk.GameStart, fk.PreCardEffect},
  frequency = Skill.Compulsory,
  can_trigger = function(self, event, target, player, data)
    if not player:hasSkill(self) then return false end
    if event == fk.PreCardEffect then
      return data.to == player.id and data.card.name == "raid_and_frontal_attack"
    end
    return true
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    if event == fk.GameStart then
      local name = "raid_and_frontal_attack"
      local tianzuo_derivecards = {{name, Card.Spade, 2}, {name, Card.Spade, 4}, {name, Card.Spade, 6}, {name, Card.Spade, 8},
      {name, Card.Club, 3},{name, Card.Club, 5},{name, Card.Club, 7},{name, Card.Club, 9}}
      for _, id in ipairs(U.prepareDeriveCards(room, tianzuo_derivecards, "tianzuo_derivecards")) do
        if room:getCardArea(id) == Card.Void then
          table.removeOne(room.void, id)
          table.insert(room.draw_pile, math.random(1, #room.draw_pile), id)
          room:setCardArea(id, Card.DrawPile, nil)
        end
      end
      room:doBroadcastNotify("UpdateDrawPile", tostring(#room.draw_pile))
    else
      return true
    end
  end,
}
local zhinang = { "ex_nihilo", "dismantlement", "nullification" }
local lingce = fk.CreateTriggerSkill{
  name = "joy__lingce",
  anim_type = "drawcard",
  events = {fk.CardUsing},
  frequency = Skill.Compulsory,
  can_trigger = function(self, event, target, player, data)
    return
      player:hasSkill(self) and
      not data.card:isVirtual() and
      (
        table.contains(zhinang, data.card.trueName) or
        table.contains(player:getTableMark( "@$joy__dinghan"), data.card.trueName) or
        data.card.trueName == "raid_and_frontal_attack"
      )
  end,
  on_use = function(self, event, target, player, data)
    player:drawCards(1, self.name)
  end,
}
local dinghan = fk.CreateTriggerSkill{
  name = "joy__dinghan",
  anim_type = "defensive",
  events = {fk.TargetConfirming, fk.TurnStart},
  can_trigger = function(self, event, target, player, data)
    if target ~= player or not player:hasSkill(self) then
      return false
    end

    if event == fk.TargetConfirming then
      return
        data.card.type == Card.TypeTrick and
        data.card.name ~= "raid_and_frontal_attack" and
        not table.contains(type(player:getMark("@$joy__dinghan")) == "table" and player:getMark("@$joy__dinghan") or {}, data.card.trueName)
    else
      return true
    end
  end,
  on_cost = function(self, event, target, player, data)
    if event == fk.TurnStart then
      local room = player.room

      local dinghanRecord = type(player:getMark("@$joy__dinghan")) == "table" and player:getMark("@$joy__dinghan") or {}
      local allTricksName = {}
      for _, id in ipairs(Fk:getAllCardIds()) do
        local card = Fk:getCardById(id)
        if card.type == Card.TypeTrick and not card.is_derived and not table.contains(dinghanRecord, card.trueName) then
          table.insertIfNeed(allTricksName, card.trueName)
        end
      end

      local choices = {"Cancel"}
      if #allTricksName > 0 then
        table.insert(choices, 1, "joy__dinghan_addRecord")
      end
      if #dinghanRecord > 0 then
        table.insert(choices, 2, "joy__dinghan_removeRecord")
      end
      local choice = room:askForChoice(player, choices, self.name)

      if choice == "Cancel" then
        return false
      end

      local cardName = room:askForChoice(player, choice == "joy__dinghan_addRecord" and allTricksName or dinghanRecord, self.name)

      self.cost_data = { choice = choice, cardName = cardName }
    end

    return true
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    local dinghanRecord = type(player:getMark("@$joy__dinghan")) == "table" and player:getMark("@$joy__dinghan") or {}
    if event == fk.TargetConfirming then
      table.insert(dinghanRecord, data.card.trueName)
      room:setPlayerMark(player, "@$joy__dinghan", dinghanRecord)
      AimGroup:cancelTarget(data, player.id)
      return true
    else
      local costData = self.cost_data
      if costData.choice == "joy__dinghan_addRecord" then
        table.insert(dinghanRecord, costData.cardName)
      else
        table.removeOne(dinghanRecord, costData.cardName)
      end
      room:setPlayerMark(player, "@$joy__dinghan", #dinghanRecord > 0 and dinghanRecord or 0)
    end
  end,
}
godxunyu:addSkill(tianzuo)
godxunyu:addSkill(lingce)
godxunyu:addSkill(dinghan)
Fk:loadTranslationTable{
  ["joy__godxunyu"] = "神荀彧",
  ["#joy__godxunyu"] = "洞心先识",

  ["joy__tianzuo"] = "天佐",
  [":joy__tianzuo"] = "锁定技，游戏开始时，将8张【奇正相生】加入牌堆；【奇正相生】对你无效。",
  ["joy__lingce"] = "灵策",
  [":joy__lingce"] = "锁定技，当非虚拟且非转化的锦囊牌被使用时，若此牌的牌名属于智囊牌名、“定汉”已记录的牌名或【奇正相生】时，你摸一张牌。"..
  "<br><font color='grey'>智囊牌：【过河拆桥】、【无中生有】、【无懈可击】",
  ["joy__dinghan"] = "定汉",
  [":joy__dinghan"] = "当你成为锦囊牌的目标时，若此牌牌名未被“定汉”记录，则“定汉”记录此牌名，然后取消此目标；回合开始时，你可以为“定汉”记录增加或移除"..
  "一种锦囊牌的牌名。",
  ["@$joy__dinghan"] = "定汉",
  ["joy__dinghan_addRecord"] = "增加牌名",
  ["joy__dinghan_removeRecord"] = "移除牌名",

  ["$joy__tianzuo1"] = "此时进之多弊，守之多利，愿主公熟虑。",
  ["$joy__tianzuo2"] = "主公若不时定，待四方生心，则无及矣。",
  ["$joy__lingce1"] = "绍士卒虽众，其实难用，必无为也。",
  ["$joy__lingce2"] = "袁军不过一盘砂砾，主公用奇则散。",
  ["$joy__dinghan1"] = "杀身有地，报国有时。",
  ["$joy__dinghan2"] = "益国之事，虽死弗避。",
  ["~joy__godxunyu"] = "宁鸣而死，不默而生……",

  ["$joy__godxunyu_win_audio"] = "汉室复兴，指日可待！",
}

local godsunce = General(extension, "joy__godsunce", "god", 1, 6)
local yingba = fk.CreateActiveSkill{
  name = "joy__yingba",
  anim_type = "offensive",
  target_num = 1,
  can_use = function(self, player)
    return player:usedSkillTimes(self.name, Player.HistoryPhase) == 0
  end,
  card_filter = function(self, to_select, selected)
    return false
  end,
  target_filter = function(self, to_select, selected, selected_cards)
    return Self.id ~= to_select and Fk:currentRoom():getPlayerById(to_select).maxHp > 1
  end,
  on_use = function(self, room, effect)
    local to = room:getPlayerById(effect.tos[1])
    room:changeMaxHp(to, -1)
    room:addPlayerMark(to, "@joy__yingba_pingding")

    room:changeMaxHp(room:getPlayerById(effect.from), -1)
  end,
}
local yingbaBuff = fk.CreateTargetModSkill{
  name = "#joy__yingba-buff",
  bypass_distances =  function(self, player, skill, card, to)
    return player:hasSkill("joy__yingba") and to and to:getMark("@joy__yingba_pingding") > 0
  end,
}
local fuhai = fk.CreateTriggerSkill{
  name = "joy__fuhai",
  events = {fk.TargetSpecified, fk.Death},
  anim_type = "drawcard",
  frequency = Skill.Compulsory,
  can_trigger = function(self, event, target, player, data)
    if not player:hasSkill(self) then return false end
    if event == fk.TargetSpecified then
      return target == player and player.room:getPlayerById(data.to):getMark("@joy__yingba_pingding") > 0
    else
      return player.room:getPlayerById(data.who):getMark("@joy__yingba_pingding") > 0
    end
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    if event == fk.TargetSpecified then
      data.disresponsiveList = data.disresponsiveList or {}
      table.insert(data.disresponsiveList, data.to)
      if player:getMark("joy__fuhai_draw-turn") < 2 then
        room:addPlayerMark(player, "joy__fuhai_draw-turn")
        player:drawCards(1, self.name)
      end
    else
      local pingdingNum = target:getMark("@joy__yingba_pingding")
      room:changeMaxHp(player, pingdingNum)
      player:drawCards(pingdingNum, self.name)
    end
  end,
}
local pinghe = fk.CreateTriggerSkill{
  name = "joy__pinghe",
  events = {fk.DamageInflicted},
  anim_type = "defensive",
  frequency = Skill.Compulsory,
  can_trigger = function(self, event, target, player, data)
    return
      target == player and
      player:hasSkill(self) and
      player.maxHp > 1 and
      not player:isKongcheng() and
      data.from and
      data.from ~= player
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    room:changeMaxHp(player, -1)
    local tos, cardId = room:askForChooseCardAndPlayers(player, table.map(room:getOtherPlayers(player, false), function(p)
      return p.id end), 1, 1, ".|.|.|hand", "#joy__pinghe-give", self.name, false, true )
    room:obtainCard(tos[1], cardId, false, fk.ReasonGive)
    if player:hasSkill(yingba.name, true) and data.from:isAlive() then
      room:addPlayerMark(data.from, "@joy__yingba_pingding")
    end
    return true
  end,
}
local pingheBuff = fk.CreateMaxCardsSkill {
  name = "#joy__pinghe-buff",
  frequency = Skill.Compulsory,
  fixed_func = function(self, player)
    return player:hasSkill("joy__pinghe") and player:getLostHp() or nil
  end
}
yingba:addRelatedSkill(yingbaBuff)
pinghe:addRelatedSkill(pingheBuff)
godsunce:addSkill(yingba)
godsunce:addSkill(fuhai)
godsunce:addSkill(pinghe)

local godsunce_win = fk.CreateActiveSkill{ name = "joy__godsunce_win_audio" }
godsunce_win.package = extension
Fk:addSkill(godsunce_win)

Fk:loadTranslationTable{
  ["joy__godsunce"] = "神孙策",
  ["#joy__godsunce"] = "踞江鬼雄",

  ["joy__yingba"] = "英霸",
  [":joy__yingba"] = "出牌阶段限一次，你可以令一名体力上限大于1的其他角色减1点体力上限，并令其获得一枚“平定”标记，然后你减1点体力上限；"..
  "你对拥有“平定”标记的角色使用牌无距离限制。",
  ["joy__fuhai"] = "覆海",
  [":joy__fuhai"] = "锁定技，①当你使用牌指定拥有“平定”标记的角色为目标后，其不能响应此牌，且你摸一张牌（每回合限摸两张）；②当拥有“平定”标记的角色死亡时，你增加X点体力上限并摸X张牌（X为其“平定”标记数）。",
  ["joy__pinghe"] = "冯河",
  [":joy__pinghe"] = "锁定技，你的手牌上限基值为你已损失的体力值；当你受到其他角色造成的伤害时，若你的体力上限大于1且你有手牌，你防止此伤害，"..
  "减1点体力上限并将一张手牌交给一名其他角色，然后若你有技能〖英霸〗，伤害来源获得一枚“平定”标记。",
  ["#joy__pinghe-give"] = "冯河：请交给一名其他角色一张手牌",
  ["@joy__yingba_pingding"] = "平定",

  ["$joy__yingba1"] = "从我者可免，拒我者难容！",
  ["$joy__yingba2"] = "卧榻之侧，岂容他人鼾睡！",
  ["$joy__fuhai1"] = "翻江复蹈海，六合定乾坤！",
  ["$joy__fuhai2"] = "力攻平江东，威名扬天下！",
  ["$joy__pinghe1"] = "不过胆小鼠辈，吾等有何惧哉！",
  ["$joy__pinghe2"] = "只可得胜而返，岂能败战而归！",
  ["~joy__godsunce"] = "无耻小人！竟敢暗算于我……",

  ["$joy__godsunce_win_audio"] = "平定三郡，稳据江东！",
}

local godlvmeng = General(extension, "joy__godlvmeng", "god", 3)
local shelie = fk.CreateTriggerSkill{
  name = "joy__shelie",
  anim_type = "drawcard",
  frequency = Skill.Compulsory,
  events = {fk.EventPhaseStart},
  can_trigger = function(self, event, target, player, data)
    return target == player and player:hasSkill(self) and player.phase == Player.Draw
  end,
  on_use = function(self, event, target, player, data)
     return Fk.skills["shelie"]:use(event, target, player, data)
  end,
}
local gongxin = fk.CreateTriggerSkill{
  name = "joy__gongxin",
  events = {fk.TargetSpecified, fk.TargetConfirmed},
  can_trigger = function(self, event, target, player, data)
    if player == target and player:hasSkill(self)
    and player:usedSkillTimes(self.name, Player.HistoryTurn) == 0 and #AimGroup:getAllTargets(data.tos) == 1 then
      local to = (event == fk.TargetSpecified) and data.to or data.from
      if to and to ~= player.id and not player.room:getPlayerById(to):isKongcheng() then
        self.cost_data = to
        return true
      end
    end
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    local to = room:getPlayerById(self.cost_data)
    local cards = to.player_cards[Player.Hand]
    local red = table.filter(cards, function (id) return Fk:getCardById(id).color == Card.Red end)
    local ids, choice = U.askforChooseCardsAndChoice(player, red, {"joy__gongxin_obtaincard", "gongxin_put"},
    self.name, "#joy__gongxin-view", {"Cancel"}, 1, 1, cards)
    if #ids > 0 then
      player:showCards(ids)
      if choice == "joy__gongxin_obtaincard" then
        room:moveCardTo(ids, Card.PlayerHand, player, fk.ReasonPrey, self.name, nil, true, player.id)
      else
        room:moveCardTo(ids, Card.DrawPile, nil, fk.ReasonPut, self.name, nil, true)
      end
    end
  end,
}
godlvmeng:addSkill(shelie)
godlvmeng:addSkill(gongxin)
Fk:loadTranslationTable{
  ["joy__godlvmeng"] = "神吕蒙",
  ["#joy__godlvmeng"] = "圣光之国士",
  ["joy__shelie"] = "涉猎",
  [":joy__shelie"] = "锁定技，摸牌阶段，你改为亮出牌堆顶五张牌，获得不同花色的牌各一张。",
  ["joy__gongxin"] = "攻心",
  [":joy__gongxin"] = "每回合限一次，每当你使用牌指定其他角色为唯一目标后，或你成为其他角色使用牌的唯一目标后，你可以观看该角色的手牌并可以展示其中的一张红色牌，你获得此牌或将之置于牌堆顶。",
  ["#joy__gongxin-active"] = "是否发动 攻心，观看%dest的手牌",
  ["#joy__gongxin-view"] = "攻心：可以选择一张红色牌",
  ["joy__gongxin_obtaincard"] = "获得此牌",

}


local godguojia = General(extension, "joy__godguojia", "god", 3)

local godHuishi = fk.CreateActiveSkill{
  name = "joy__god_huishi",
  anim_type = "drawcard",
  can_use = function(self, player)
    return player:usedSkillTimes(self.name, Player.HistoryPhase) == 0 and player.maxHp < 10
  end,
  card_filter = function(self, to_select, selected)
    return false
  end,
  target_filter = function(self, to_select, selected, selected_cards)
    return false
  end,
  on_use = function(self, room, effect)
    local from = room:getPlayerById(effect.from)

    local cardsJudged = {}
    while from.maxHp < 10 do
      local parsePattern = table.concat(table.map(cardsJudged, function(card)
        return card:getSuitString()
      end), ",")

      local judge = {
        who = from,
        reason = self.name,
        pattern = ".|.|" .. (parsePattern == "" and "." or "^(" .. parsePattern .. ")"),
        skipDrop = true,
      }
      room:judge(judge)

      table.insert(cardsJudged, judge.card)

      if
        not table.every(cardsJudged, function(card)
          return card == judge.card or judge.card:compareSuitWith(card, true)
        end) or
        not room:askForSkillInvoke(from, self.name, nil, "#mobile__god_huishi-ask")
      then
        break
      end

      room:changeMaxHp(from, 1)
    end

    local alivePlayerIds = table.map(room.alive_players, function(p)
      return p.id
    end)

    cardsJudged = table.filter(cardsJudged, function(card)
      return room:getCardArea(card.id) == Card.Processing
    end)
    if #cardsJudged == 0 then
      return false
    end

    local targets = room:askForChoosePlayers(from, alivePlayerIds, 1, 1, "#mobile__god_huishi-give", self.name, true)
    
    if #targets > 0 then
      local to = targets[1]
      local pack = Fk:cloneCard("slash")
      pack:addSubcards(table.map(cardsJudged, function(card)
        return card:getEffectiveId()
      end))
      room:obtainCard(to, pack, true, fk.ReasonGive)

      if
        table.every(room.alive_players, function(p)
          return p:getHandcardNum() <= room:getPlayerById(to):getHandcardNum()
        end)
      then
        room:changeMaxHp(from, -1)
      end
    else
      room:moveCards({
        ids = table.map(cardsJudged, function(card)
          return card:getEffectiveId()
        end),
        toArea = Card.DiscardPile,
        moveReason = fk.ReasonPutIntoDiscardPile,
        skillName = self.name,
      })
    end
  end,
}
local tianyi = fk.CreateTriggerSkill{
  name = "joy__tianyi",
  anim_type = "support",
  events = {fk.EventPhaseStart},
  frequency = Skill.Wake,
  can_trigger = function(self, event, target, player, data)
    return
      target == player and
      player.phase == Player.Start and
      player:hasSkill(self) and
      player:usedSkillTimes(self.name, Player.HistoryGame) < 1
  end,
  can_wake = function(self, event, target, player, data)
    return table.every(player.room.alive_players, function(p)
      return #player.room.logic:getActualDamageEvents( 1, function(e) return e.data[1].to == p end, Player.HistoryGame) > 0
    end)
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    room:changeMaxHp(player, 2)
    room:recover({
      who = player,
      num = 1,
      recoverBy = player,
      skillName = self.name,
    })

    local tos = room:askForChoosePlayers(player, table.map(room.alive_players, Util.IdMapper), 1, 1, "#mobile__tianyi-choose", self.name, false)
    if #tos > 0 then
      room:handleAddLoseSkills(room:getPlayerById(tos[1]), "joy__zuoxing")
    end
  end,
}
local zuoxing = fk.CreateViewAsSkill{
  name = "joy__zuoxing",
  prompt = "#zuoxing",
  interaction = function(self,player)
    local names, all_names = {} , {}
    for _, id in ipairs(Fk:getAllCardIds()) do
      local card = Fk:getCardById(id)
      if card:isCommonTrick() and not card.is_derived and not table.contains(all_names, card.name) then
        table.insert(all_names, card.name)
        local to_use = Fk:cloneCard(card.name)
        if Self:canUse(to_use) and not Self:prohibitUse(to_use) then
          table.insert(names, card.name)
        end
      end
    end
    if #names == 0 then return false end
    return UI.ComboBox {choices = names, all_choices = all_names}
  end,
  enabled_at_play = function(self, player)
    return
      player:usedSkillTimes(self.name, Player.HistoryPhase) == 0 and
      table.find(Fk:currentRoom().alive_players, function(p)
        return table.find({ p.general, p.deputyGeneral }, function(name) return string.find(name, "joy__godguojia") end) and p.maxHp > 1
      end)
  end,
  card_filter = Util.FalseFunc,
  view_as = function(self, cards)
    if not self.interaction.data then return end
    local card = Fk:cloneCard(self.interaction.data)
    card.skillName = self.name
    return card
  end,
  before_use = function(self, player)
    local room = player.room
    local firstGodGuojia = table.filter(room:getAlivePlayers(), function(p)
      return table.find({ p.general, p.deputyGeneral }, function(name) return string.find(name, "joy__godguojia") end) and p.maxHp > 1
    end)

    if firstGodGuojia then
      room:changeMaxHp(firstGodGuojia[1], -1)
    end
  end,
}
godguojia:addSkill(godHuishi)
godguojia:addSkill(tianyi)
godguojia:addSkill("mobile__limited_huishi")
godguojia:addRelatedSkill(zuoxing)
Fk:loadTranslationTable{
  ["joy__godguojia"] = "神郭嘉",
  ["#joy__godguojia"] = "星月奇佐",
  ["joy__god_huishi"] = "慧识",
  [":joy__god_huishi"] = "出牌阶段限一次，若你的体力上限小于10，你可以判定，若结果与本次流程中的其他判定结果均不同，且你的体力上限小于10，你可加1点"..
  "体力上限并重复此流程。最后你将本次流程中所有生效的判定牌交给一名角色，若其手牌为全场最多，你减1点体力上限。",
  ["joy__tianyi"] = "天翊",
  [":joy__tianyi"] = "觉醒技，准备阶段开始时，若所有存活角色于本局游戏内均受到过伤害，你加2点体力上限，回复1点体力，令一名角色获得技能“佐幸”。",
  ["joy__zuoxing"] = "佐幸",
  [":joy__zuoxing"] = "出牌阶段限一次，你可以令神郭嘉减1点体力上限，视为使用一张普通锦囊牌。"..
  '<br /><font color="green">（村：不会整欢杀佐幸，直接照搬原版）</font>',
}

local godluxun = General(extension, "joy__godluxun", "god", 4)
local cuike = fk.CreateTriggerSkill{
  name = "joy__cuike",
  anim_type = "offensive",
  events = {fk.EventPhaseStart},
  can_trigger = function(self, event, target, player, data)
    return target == player and player:hasSkill(self) and player.phase == Player.Play
  end,
  on_cost = Util.TrueFunc,
  on_use = function(self, event, target, player, data)
    local room = player.room
    if player:getMark("@junlue") % 2 == 1 then
      local tos = room:askForChoosePlayers(player, table.map(room.alive_players, Util.IdMapper),
      1, 1, "#cuike-damage", self.name, true)
      if #tos > 0 then
        room:damage {
          from = player, to = room:getPlayerById(tos[1]),
          damage = 1, skillName = self.name
        }
      end
    else
      local targets = {}
      for _, p in ipairs(room.alive_players) do
        if not (p:isAllNude() and p.chained) then
          table.insert(targets, p.id)
        end
      end
      local tos = room:askForChoosePlayers(player, targets, 1, 1, "#cuike-discard", self.name, true)
      if #tos > 0 then
        local to = room:getPlayerById(tos[1])
        if not to:isAllNude() then
          local cid = room:askForCardChosen(player, to, "hej", self.name)
          room:throwCard(cid, self.name, to, player)
        end
        if not (to.dead or to.chained) then
          to:setChainState(true)
        end
      end
    end
    if player.dead then return false end
    if player:getMark("@junlue") > #room.alive_players then
      if room:askForSkillInvoke(player, self.name, nil, "#cuike-shenfen") then
        room:setPlayerMark(player, "@junlue", 0)
        for _, p in ipairs(room:getOtherPlayers(player)) do
          if not p.dead then
            room:damage {
              from = player, to = p,
              damage = 1, skillName = self.name
            }
          end
        end
      end
    end
  end,
}
godluxun:addSkill("junlue")
godluxun:addSkill(cuike)
godluxun:addSkill("zhanhuo")
Fk:loadTranslationTable{
  ["joy__godluxun"] = "神陆逊",
  ["#joy__godluxun"] = "红莲业火",
   ["joy__cuike"] = "摧克",
  [":joy__cuike"] = "出牌阶段开始时，若你的“军略”数为：奇数，你可以对一名角色造成1点伤害；偶数，你可以弃置一名角色区域里的一张牌，令其横置。然后若“军略”数大于场上存活人数，你可弃置全部“军略”，对所有其他角色各造成1点伤害。",

  ["$joy__cuike1"] = "克险摧难，军略当先。",
  ["$joy__cuike2"] = "摧敌心神，克敌计谋。",
}

local godzhugeliang = General(extension, "joy__godzhugeliang", "god", 3)
local kuangfeng = fk.CreateTriggerSkill{
  name = "joy__kuangfeng",
  events = {fk.EventPhaseEnd},
  anim_type = "offensive",
  expand_pile = "star",
  can_trigger = function(self, event, target, player, data)
    if not player:hasSkill(self) then return false end
      return target == player and player.phase == Player.Play and #player:getPile("star") > 0
  end,
  on_cost = function(self, event, target, player, data)
      local room = player.room
      local targets = room:askForChoosePlayers(player, table.map(room.alive_players, Util.IdMapper), 1, #room.alive_players, "#joy__kuangfeng-target", self.name,true)
      if #targets > 0 then
        local cids = room:askForCard(player, #targets, #targets, false, self.name, true, ".|.|.|star", "#joy__kuangfeng-card:::"..#targets, "star")
        if #cids > 0 then
          self.cost_data = {targets, cids}
          return true
        end
      end
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    room:moveCardTo(self.cost_data[2], Card.DiscardPile, nil, fk.ReasonPutIntoDiscardPile, self.name, "star")
    for _, id in ipairs(self.cost_data[1]) do
      local p = room:getPlayerById(id)
      if not p.dead then
        room:damage{from = player, to = p, damage = 1, skillName = self.name}
      end
    end
  end,

}
local dawu = fk.CreateTriggerSkill{
  name = "joy__dawu",
  anim_type = "defensive",
  events = {fk.EventPhaseStart, fk.DamageInflicted},
  expand_pile = "star",
  can_trigger = function(self, event, target, player, data)
    if event == fk.EventPhaseStart then
      return target == player and  player:hasSkill(self)  and player.phase == Player.Finish and #player:getPile("star") > 0
    else
      return target == player and player:getMark("@@joy__dawu") > 0 and data.damageType == fk.NormalDamage
    end
  end,
  on_cost = function(self, event, target, player, data)
    if event == fk.EventPhaseStart then
      local room = player.room
      local cids = room:askForCard(player, 1, 1, false, self.name, true, ".|.|.|star", "#joy__dawu-card", "star")
      if #cids > 0 then
        self.cost_data = {player, cids}
        return true
      end
    else
      return true
    end
  end,
  on_use = function(self, event, target, player, data)
    if event == fk.EventPhaseStart then
      local room = player.room
      room:moveCardTo(self.cost_data[2], Card.DiscardPile, nil, fk.ReasonPutIntoDiscardPile, self.name, "star")
        room:addPlayerMark(player, "@@joy__dawu")
    else
      data.damage = data.damage - 1
    end
  end,

  refresh_events = {fk.TurnStart},
  can_refresh = function(self, event, target, player, data)
    return target == player and player:getMark("@@joy__dawu") ~= 0
  end,
  on_refresh = function(self, event, target, player, data)
    local room = player.room
    room:removePlayerMark(player, "@@joy__dawu")
  end,
}
godzhugeliang:addSkill("qixing")
godzhugeliang:addSkill(kuangfeng)
godzhugeliang:addSkill(dawu)
Fk:loadTranslationTable{
  ["joy__godzhugeliang"] = "神诸葛亮",
  ["#joy__godzhugeliang"] = "赤壁的妖术师",
  
  ["joy__kuangfeng"] = "狂风",
  [":joy__kuangfeng"] = "出牌阶段结束时，你可以将任意张“星”置入弃牌堆并选择等量名角色对其各造成一点伤害。",
  ["joy__dawu"] = "大雾",
  [":joy__dawu"] = "结束阶段，你可以将一张“星”置入弃牌堆，然后直到你的下回合开始之前，你受到的非属性伤害-1。",

  ["#joy__kuangfeng-card"] = "狂风：选择将%arg张“星”置入弃牌堆",
  ["#joy__kuangfeng-target"] = "狂风：请选择不大于“星”数量的角色，然后弃置等量的星，对其各造成一点伤害",
  ["@@joy__dawu"] = "大雾",
  ["#joy__dawu-card"] = "大雾：你可以将一张“星”置入弃牌堆，然后你受到的非属性伤害-1直到你的下回合开始",

}

local godzhangliao = General(extension, "joy__godzhangliao", "god", 4)
local duorui = fk.CreateTriggerSkill{
  name = "joy__duorui",
  events = {fk.EventPhaseStart},
  can_trigger = function(self, event, target, player, data)
    if event == fk.EventPhaseStart and player == target and player:hasSkill(self) and player.phase == Player.Play then
      return table.find(player.room.alive_players, function(p) return p ~= player and not p:isKongcheng() end)
    end
  end,
  on_cost = function (self,event, target, player, data)
    local targets = table.filter(player.room:getOtherPlayers(player), function (p) return not p:isKongcheng() end)
    local to = player.room:askForChoosePlayers(player, table.map(targets, Util.IdMapper), 1, 1, "#joy__duorui-choose",self.name,true)
    if #to > 0 then
      self.cost_data = to[1]
      return true
    end
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    local to = room:getPlayerById(self.cost_data)
    local id = room:askForCardChosen(player, to, { card_data = { { "$Hand", to.player_cards[Player.Hand] } } }, self.name)
    local color = Fk:getCardById(id):getColorString()
    if color ~= "nocolor" then
      local mark = to:getTableMark( "@joy__duorui-turn")
      table.insertIfNeed(mark, color)
      room:setPlayerMark(to, "@joy__duorui-turn", mark)
    end
    room:moveCardTo(id, Card.PlayerHand, player, fk.ReasonPrey, self.name, nil, true, player.id)
  end,
}
local duorui_trigger = fk.CreateTriggerSkill{
  name = "#joy__duorui_trigger",
  mute = true,
  events = {fk.CardUsing},
  can_trigger = function(self, event, target, player, data)
    return target == player and player == player.room.current
    and table.find(player.room.alive_players, function (p)
      return table.contains(p:getTableMark( "@joy__duorui-turn"), data.card:getColorString())
    end)
  end,
  on_cost = Util.TrueFunc,
  on_use = function(self, event, target, player, data)
    data.disresponsiveList = data.disresponsiveList or {}
    for _, p in ipairs(player.room.alive_players) do
      if table.contains(p:getTableMark( "@joy__duorui-turn"), data.card:getColorString()) then
        table.insertIfNeed(data.disresponsiveList, p.id)
      end
    end
  end,
}
local zhiti = fk.CreateTriggerSkill{
  name = "joy__zhiti",
  anim_type = "offensive",
  frequency = Skill.Compulsory,
  events = {fk.DrawNCards},
  can_trigger = function(self,event,target,player,data)
    return target == player and player:hasSkill(self)
    and #table.filter(player.room.alive_players, function(p) return p:isWounded() end) > 1
  end,
  on_use = function(self, event, target, player, data)
    data.n = data.n + 1
  end,
}
local zhiti_targetmod = fk.CreateTargetModSkill{
  name = "#joy__zhiti_targetmod",
  residue_func = function(self, player, skill, scope)
    if skill.trueName == "slash_skill" and player:hasSkill(zhiti) then
      local n = 0
      for _, p in ipairs(Fk:currentRoom().alive_players) do
        if p:isWounded() then
          n = n + 1
        end
      end
      if n > 2 then
        return 1
      end
    end
  end,
}
duorui:addRelatedSkill(duorui_trigger)
zhiti:addRelatedSkill(zhiti_targetmod)
godzhangliao:addSkill(duorui)
godzhangliao:addSkill(zhiti)

Fk:loadTranslationTable{
  ["joy__godzhangliao"] = "神张辽",
  ["#joy__godzhangliao"] = "雁门之刑天",

  ["joy__duorui"] = "夺锐",
  [":joy__duorui"] = "出牌阶段开始时，你可以选择一名有手牌的其他角色，观看并获得其一张手牌，然后本回合其无法响应你使用的该牌颜色的牌。",
  ["joy__zhiti"] = "止啼",
  [":joy__zhiti"] = "锁定技，若存活的已受伤角色数量：大于1，你摸牌阶段摸牌数量+1；大于2，你出牌阶段可使用【杀】的次数+1。",

  ["#joy__duorui_trigger"] = "夺锐",
  ["#joy__duorui-choose"] = "夺锐：观看并获得一名其他角色的一张手牌",
  ["joy__duoruiget"] = "确定",
  ["@joy__duorui-turn"] = "夺锐",
}

local godsunquan = General(extension, "joy__godsunquan", "god", 4)
local quanxue = fk.CreateTriggerSkill{
  name = "joy__quanxue",
  events = {fk.EventPhaseStart,fk.TurnStart},
  can_trigger = function(self, event, target, player, data)
    if event == fk.EventPhaseStart then
      return player == target and player:hasSkill(self) and player.phase == Player.Play
    elseif event == fk.TurnStart then
      return target:getMark("@@joy__xue") > 0
    end
  end,
  on_cost = function (self,event, target, player, data)
    if event == fk.TurnStart then return true end
    local tos = player.room:askForChoosePlayers(player,table.map(player.room:getOtherPlayers(player),
    function(p) return p.id end),1,2,"#joy__quanxue-ask",self.name,true)
    if #tos > 0 then
      self.cost_data = {tos}
      return true
    end
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    if event == fk.EventPhaseStart then
      local tos = self.cost_data[1]
      for _, pid in ipairs(tos) do
        local p = room:getPlayerById(pid)
        if not p.dead then
          room:setPlayerMark(p,"@@joy__xue",1)
        end
      end
    else
      room:setPlayerMark(target,"@@joy__xue",0)
      local choices = {"joy__quanxue_cantuse","joy__quanxue_losehp"}
      local choice = room:askForChoice(target,choices,self.name,"joy__quanxue-choice")
      if choice == "joy__quanxue_losehp" and not target.dead then
        room:loseHp(target,1,self.name)
      elseif choice == "joy__quanxue_cantuse" then
        room:setPlayerMark(target,"@@joy__quanxue_cantuse-turn",1)
      end
      local targets = {}
      for _, p in ipairs(player.room:getAlivePlayers()) do
        if p:hasSkill("joy__dingli") then
          if not p.dead and not target.dead and p:hasSkill("joy__dingli") and p:getMark("joy__dingli-round") == 0 then
            local n1 = p.hp
            local n2 = target.hp
            local n = math.min(n1 - n2,2)
            if n1 <= n2 then
              if room:askForSkillInvoke(p,"joy__dingli",data,"#joy__dingli-ask1") then
                player.room:recover({
                  who = p,
                  num = 1,
                  recoverBy = p,
                  skillName = "joy__quanxue"
                  })
                p:broadcastSkillInvoke("joy__dingli")
                room:notifySkillInvoked(p, "joy__dingli")
                room:setPlayerMark(p,"joy__dingli-round",1)
              end
            elseif room:askForSkillInvoke(p,"joy__dingli",data,"#joy__dingli-ask2:::"..n) then
              p:drawCards(n,"joy__dingli")
              p:broadcastSkillInvoke("joy__dingli")
              room:notifySkillInvoked(p, "joy__dingli")
              room:setPlayerMark(p,"joy__dingli-round",1)
            end
          end
        end
      end
    end
  end,
}
local quanxue_cantuse = fk.CreateProhibitSkill{
  name = "#joy__quanxue_cantuse",
  is_prohibited = function(self, from, to, card)
    return from:getMark("@@joy__quanxue_cantuse-turn") > 0 and from ~= to and from.phase == Player.Play
  end,
}
local shehu = fk.CreateTriggerSkill{
  name = "joy__shehu",
  anim_type = "offensive",
  events = {fk.TargetSpecified},
  frequency = Skill.Compulsory,
  can_trigger = function(self, event, target, player, data)
    local to = player.room:getPlayerById(data.to)
    return target == player and player:hasSkill(self) and data.card.trueName == "slash" and to:getMark("@@joy__xue") > 0 and not to:isKongcheng()
  end,
  on_use = function(self, event, target, player, data)
    local to = player.room:getPlayerById(data.to)
    if not player.dead and not to.dead then
      local card = player.room:askForCardChosen(player, to, "h", self.name)
      player.room:throwCard(card,self.name,to,player)
    end
  end,
}
local dingli = fk.CreateTriggerSkill{
  name = "joy__dingli",
  anim_type = "support",
}
quanxue:addRelatedSkill(quanxue_cantuse)
godsunquan:addSkill(quanxue)
godsunquan:addSkill(shehu)
godsunquan:addSkill(dingli)
Fk:loadTranslationTable{
  ["joy__godsunquan"] = "神孙权",
  ["#joy__godsunquan"] = "十万馒头",

  ["joy__quanxue"] = "劝学",
  [":joy__quanxue"] = "出牌阶段开始时，你可以选择至多两名其他角色各获得一个“学”;拥有“学”的角色回合开始时移除标记并选择一项："..
  "1，本回合出牌阶段无法对其他角色使用牌；2，失去一点体力。",
  ["joy__shehu"] = "射虎",
  [":joy__shehu"] = "锁定技，当你对有“学”的角色使用杀时，弃置其一张手牌。",
  ["joy__dingli"] = "鼎立",
  [":joy__dingli"] = "每轮限一次，当其他角色移除“学”时，若其体力值大于等于你，你可以恢复一点体力；若其体力值小于等于你，你可以摸X张牌（X为你与其体力值之差，且至多为2）。",

  ["@@joy__xue"] = "学",
  ["#joy__quanxue-ask"] = "劝学：你可以选择至多两名其他角色各获得一个“学”",
  ["joy__quanxue-choice"] = "劝学：选择一项并移除“学”标记",
  ["joy__quanxue_cantuse"] = "本回合出牌阶段无法对其他角色使用牌",
  ["joy__quanxue_losehp"] = "失去一点体力",
  ["@@joy__quanxue_cantuse-turn"] = "劝学",

  ["#joy__dingli-ask1"] = "鼎立:每轮限一次，是否选择回复1点体力",
  ["#joy__dingli-ask2"] = "鼎立：每轮限一次，是否选择摸%arg张牌",
}

local joy__godzuoci = General(extension, "joy__godzuoci", "god", 3)

GetHuanPile = function (room)
  local cards = room:getTag("joy__huanshu_pile")
  if cards == nil then
    cards = {}
    -- 会忽略模式牌堆黑名单（例如忠胆英杰） so bad
    for _, id in ipairs(Fk:getAllCardIds()) do
      local c = Fk:getCardById(id, true)
      if not c.is_derived then
        local card = room:printCard(c.name, c.suit, c.number)
        room:setCardMark(card, MarkEnum.DestructIntoDiscard, 1)
        room:setCardMark(card, "@@joy__huanshu_card", 1)
        table.insert(cards, card.id)
      end
    end
    table.shuffle(cards)
    room:setTag("joy__huanshu_pile", cards)
  end
  local temp = table.filter(cards, function(id) return room:getCardArea(id) == Card.Void end)
  return temp
end

---@param player ServerPlayer
HuanHuaCard = function (player,name,suit,number,skillName)
      local room = player.room
      local card = room:printCard(name, suit, number)
      room:setCardMark(card, MarkEnum.DestructIntoDiscard, 1)
      room:setCardMark(card, "@@joy__huanshu_card", 1)
      room:setCardMark(card, "@@joy__huanhua_card-inhand", 1)
      room:delay(300)
      
      --table.removeOne(room.void, card.id)
      room:setCardArea(card.id,Card.DrawPile)
      room:moveCardTo(card, Card.PlayerHand, player, fk.ReasonPrey, skillName)
      
      
end

---@param player ServerPlayer
GetHuanCard = function (player, n, skillName)
  local room = player.room
  if player.dead then return end
  local max_num = 2 * player.maxHp
  local has_num = #table.filter(player.player_cards[Player.Hand], function (id)
    return Fk:getCardById(id):getMark("@@joy__huanshu_card") ~= 0
  end)
  local get_num  = math.max(0, math.min(n, max_num - has_num))
  local draw_num = n - get_num
  if get_num > 0 then
    local pile = GetHuanPile(room)
    if #pile > 0 then
      local get = table.random(pile, get_num)
      room:delay(300)
      for _, id in ipairs(get) do
        table.removeOne(room.void, id)
        room:setCardArea(id, Card.DrawPile)
      end
      room:moveCardTo(get, Card.PlayerHand, player, fk.ReasonPrey, skillName)
    end
  end
  if not player.dead and draw_num > 0 then
    player:drawCards(draw_num, skillName)
  end
end

local joy__huanshu = fk.CreateTriggerSkill{
  name = "joy__huanshu",
  anim_type = "control",
  frequency = Skill.Compulsory,
  events = {fk.RoundStart, fk.Damaged, fk.EventPhaseStart, fk.AfterCardsMove},
  can_trigger = function(self, event, target, player, data)
    if not player:hasSkill(self) then return false end
    if event == fk.EventPhaseStart then
      return target == player and player.phase == Player.Play and not player:isKongcheng()
    elseif event == fk.AfterCardsMove then
      local cards = {}
      for _, move in ipairs(data) do
        if move.to and move.to ~= player.id and move.toArea == Player.Hand then
          local to = player.room:getPlayerById(move.to)
          if not to:hasSkill(self) then
            for _, info in ipairs(move.moveInfo) do
              if Fk:getCardById(info.cardId):getMark("@@joy__huanshu_card") ~= 0 and table.contains(to.player_cards[Player.Hand], info.cardId) then
                table.insertIfNeed(cards, info.cardId)
              end
            end
          end
        end
      end
      if #cards > 0 then
        self.cost_data = cards
        return true
      end
    else
      return (event == fk.RoundStart or target == player)
    end
  end,
  on_trigger = function(self, event, target, player, data)
    local n = event == fk.Damaged and data.damage or 1
    for i = 1, n do
      if player.dead then break end
      self:doCost(event, target, player, data)
    end
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    if event == fk.EventPhaseStart then
      local cards, map = {}, {}
      for _, id in ipairs(player.player_cards[Player.Hand]) do
        local c = Fk:getCardById(id)
        if c:getMark("@@joy__huanshu_card") == 1 and c:getMark("@@joy__huanhua_card-inhand") == 0 then
          table.insert(cards, id)
          if map[c.suit] == nil then
            map[c.suit] = {id}
          else
            table.insert(map[c.suit], id)
          end
        end
      end
      if #cards == 0 then return end
      --- FIXME:暂无不产生移动的换牌方式，或者直接改变牌位置的方式
      room:moveCardTo(cards, Card.Void, nil, fk.ReasonJustMove, self.name)
      if player.dead then return end
      local pile = GetHuanPile(room)
      local get = {}
      while #pile > 0 and #cards > 0 do
        local t = table.remove(pile, math.random(#pile))
        local suit = Fk:getCardById(t, true).suit
        if map[suit] and #map[suit] > 0 then
          table.insert(get, t)
          table.remove(map[suit], 1)
          table.remove(cards, 1)
        end
      end
      if #get > 0 then
        room:delay(300)
        -- FIXME:心变智慧，防止从虚空区拿出id为-1的暗牌
        for _, id in ipairs(get) do
          table.removeOne(room.void, id)
          room:setCardArea(id, Card.DrawPile)
        end
        room:moveCardTo(get, Card.PlayerHand, player, fk.ReasonPrey, self.name)
      end
    elseif event == fk.AfterCardsMove then
      room:moveCardTo(self.cost_data, Card.Void, nil, fk.ReasonJustMove, self.name)
      if not player.dead then
        player:drawCards(1, self.name)
      end
    else
      GetHuanCard (player, 2, self.name)
    end
  end,
}
local joy__huanshu_maxcards = fk.CreateMaxCardsSkill{
  name = "#joy__huanshu_maxcards",
  exclude_from = function(self, player, card)
    return player:hasSkill(joy__huanshu) and card and card:getMark("@@joy__huanshu_card") ~= 0
  end,
}
joy__huanshu:addRelatedSkill(joy__huanshu_maxcards)
joy__godzuoci:addSkill(joy__huanshu)

local joy__huanhua = fk.CreateActiveSkill{
  name = "joy__huanhua",
  card_num = 2,
  target_num = 0,
  prompt = "#joy__huanhua-prompt",
  card_filter = function(self, to_select, selected)
    if not table.contains(Self.player_cards[Player.Hand], to_select) then return false end
    local card = Fk:getCardById(to_select)
    if #selected == 0 then
      return card:getMark("@@joy__huanshu_card") == 1 and card:getMark("@@joy__huanhua_card-inhand") == 0
    elseif #selected == 1 then
      return Fk:getCardById(selected[1]):getMark("@@joy__huanshu_card") == 1
       and card:getMark("@@joy__huanhua_tar-inhand") == 0
      and (card:getMark("@@joy__huanshu_card") == 0 or Self:getMark("@joy__huanjing-turn") > 0)
    end
  end,
  can_use = function(self, player)
    return player:usedSkillTimes(self.name, Player.HistoryTurn) < (2 + player:getMark("@joy__huanjing-turn"))
  end,
  on_use = function(self, room, effect)
    local player = room:getPlayerById(effect.from)
    local huan_card = Fk:getCardById(effect.cards[1])
    local tar_card = Fk:getCardById(effect.cards[2])
    local get = huan_card.suit == tar_card.suit
    room:setCardMark(tar_card, "@@joy__huanhua_tar-inhand", 1)
    
    Fk:filterCard(huan_card.id, player)
    
    room:delay(300)
    room:moveCardTo(huan_card, Card.Void, nil, fk.ReasonJustMove, self.name)
    HuanHuaCard(player,tar_card.name, tar_card.suit, tar_card.number,self.name)
    if get then
      GetHuanCard (player, 1, self.name)
    end
  end,
}
joy__godzuoci:addSkill(joy__huanhua)

local joy__huanjing = fk.CreateActiveSkill{
  name = "joy__huanjing",
  card_num = 0,
  target_num = 0,
  frequency = Skill.Limited,
  prompt = function()
    return "#joy__huanjing-prompt:::"..math.max(1, 2 * Self:getLostHp())
  end,
  card_filter = Util.FalseFunc,
  can_use = function(self, player)
    return player:usedSkillTimes(self.name, Player.HistoryGame) == 0
  end,
  on_use = function(self, room, effect)
    local player = room:getPlayerById(effect.from)
    local x = math.max(1, 2 * player:getLostHp())
    room:addPlayerMark(player, "@joy__huanjing-turn", x)
    GetHuanCard (player, x, self.name)
  end,
}
joy__godzuoci:addSkill(joy__huanjing)

Fk:loadTranslationTable{
  ["joy__godzuoci"] = "神左慈",

  ["joy__huanshu"] = "幻术",
  [":joy__huanshu"] = 
  "<br/>锁定技；<br>·每轮开始时或每当你受到1点伤害后，你获得两张幻术牌。<br>·出牌阶段开始时，手牌中未进行“幻化”的幻术牌会随机变化为同花色的其他幻术牌。"..
  "<br /><font color='green'>①幻术牌为牌堆中随机牌的镜像，进入弃牌堆后销毁之<br>②幻术牌不计入手牌上限且至多为体力上限的两倍（超出部分将改为摸等量的牌）<br>③当幻术牌被其他角色获得时，销毁之，然后你摸一张牌。</font>"..
  '<br /><font color="grey">（村：回合开始时的变化视为重新获得牌）</font>',
  ["@@joy__huanshu_card"] = "<font color='black'>幻术</font>",

  ["joy__huanhua"] = "幻化",
  [":joy__huanhua"] = 
  "每回合限俩次，出牌阶段你可以将一张幻术手牌“幻化”为与另一张非幻术手牌的花色，点数，牌名一致。"..
  "<br /><font color='green'>①每张幻术牌只能“幻化”一次，每张牌只能被“幻化”一次。<br>②若“幻化”的对象花色相同，则额外获得一张幻术牌。</font>"..
  '<br /><font color="grey">（村：幻化视为重新获得牌）</font>',
  ["#joy__huanhua-prompt"] = "幻化：先选要被“幻化”的幻术牌，再选此幻术牌将变成的牌",
  ["#joy__huanhua_filter"] = "幻化",
  ["@@joy__huanhua_tar-inhand"] = "<font color='blue'>被幻化</font>",
  ["@@joy__huanhua_card-inhand"] = "<font color='yellow'>已幻化</font>",

  ["joy__huanjing"] = "幻境",
  [":joy__huanjing"] = "限定技，出牌阶段，你可以获得X张幻术牌，然后本回合〖幻化〗发动次数上限增加X，且幻术牌可以被“幻化”（X为你当前已损失体力值*2，且至少为1）。",
  ["#joy__huanjing-prompt"] = "幻境：获得 %arg 张幻术牌，“幻化”次数增加 %arg 次",
  ["@joy__huanjing-turn"] = "幻境",

  ["$joy__huanshu1"] = "穷则变，变则通，通则久。",
  ["$joy__huanshu2"] = "天动地宁，变化百灵。",
  ["$joy__huanhua1"] = "此事易耳。",
  ["$joy__huanhua2"] = "呵呵，这有何难？",
  ["$joy__huanjing1"] = "借小千世界，行无常勾魂！",
  ["$joy__huanjing2"] = "金丹九转，变化万端！",
  ["~joy__godzuoci"] = "当世荣华，不足贪……",
}

local godxuchu = General(extension, "joy__godxuchu", "god", 5)
godxuchu:addSkill("zhengqing")
godxuchu:addSkill("zhuangpo")

Fk:loadTranslationTable{
  ["joy__godxuchu"] = "神许褚",
  ["#joy__godxuchu"] = "嗜战的熊罴",
}

local goddengai = General(extension, "joy__goddengai", "god", 4)
local xianjin = fk.CreateTriggerSkill{
  name = "joy__xianjin",
  anim_type = "drawcard",
  frequency = Skill.Compulsory,
  events = {fk.Damage, fk.Damaged},
  can_trigger = function(self, event, target, player, data)
    return target == player and player:hasSkill(self) and player:getMark("xianjin_damage") > 1
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    room:setPlayerMark(player, "xianjin_damage", 0)

    local choices = table.map(table.filter({"1", "2", "3"}, function(n)
      return player:getMark("tuoyu"..n) == 0 end), function(n) return "tuoyu"..n end)
    if #choices > 0 then
      local choice = room:askForChoice(player, choices, self.name, "#xianjin-choice", true)
      room:setPlayerMark(player, choice, 1)
    end
    player:drawCards(#table.filter({"1", "2", "3"}, function(n) return player:getMark("tuoyu"..n) > 0 end), self.name)
  end,

  refresh_events = {fk.Damage, fk.Damaged},
  can_refresh = function(self, event, target, player, data)
    return target == player and player:hasSkill(self, true)
  end,
  on_refresh = function(self, event, target, player, data)
    player.room:addPlayerMark(player, "xianjin_damage")
  end,
}
goddengai:addSkill("tuoyu")
goddengai:addSkill(xianjin)
goddengai:addSkill("qijing")
goddengai:addRelatedSkill("cuixin")
Fk:loadTranslationTable{
  ["joy__goddengai"] = "神邓艾",
  ["#joy__goddengai"] = "带砺山河",
  ["joy__xianjin"] = "险进",
  [":joy__xianjin"] = "锁定技，当你造成或受到两次伤害后开发一个手牌副区域，摸X张牌（X为你已开发的手牌副区域数）。",
}

local selfmark = function (player,p,mark,value)
  p:setMark(mark, value)
  player:doNotify("SetPlayerMark", json.encode{
    p.id,
    mark,
    value
  })
end
local lunce = fk.CreateTriggerSkill{
  name = "joy__lunce",
  anim_type = "special",
  events = {fk.RoundStart,"fk.joy_lanhai"},
  can_trigger = function(self, event, target, player, data)
    return player:hasSkill(self) and (event == fk.RoundStart or target == player)
  end,
  on_cost = function(self, event, target, player, data)
    local room = player.room
    local ch1 = "joy_lunce1"
    local ch2 = "joy_lunce2"
    local ch3 = "joy_lunce3"
    local chs = {ch1,ch2,ch3}
    local cs = {}
    for _, c in ipairs(chs) do
      for _, p in ipairs(room.alive_players) do
        if p:getMark(c) == 0 then
          table.insertIfNeed(cs,c)
          break
        end
      end
    end
    local choice = room:askForChoices(player,cs,1,1,self.name,"选择一个计策",true,true,chs)
    if #choice > 0 then
      local tars = {}
      for _, p in ipairs(room.alive_players) do
        if p:getMark(choice[1]) == 0 then
          table.insertIfNeed(tars,p.id)
        end
      end
      if tars == 0 then return end
      local tar = room:askForChoosePlayers(player,tars,1,1,"选择一名角色，为其施加 <br>"..Fk:translate(choice[1]).."："..Fk:translate(":"..choice[1]),self.name,false)
      if #tar > 0 then
        self.cost_data = {choice[1],tar[1]}
        return true
      end
    end
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    local tar = room:getPlayerById(self.cost_data[2])
    local ch = self.cost_data[1]
    room:setPlayerMark(tar,ch,player.id)
    selfmark(player,tar,"@@"..ch,1)
    if tar == room.current then
      room:setBanner("joy_lunce-turn",1)
    end
  end,
  refresh_events = {fk.EventPhaseStart,fk.TargetSpecified,fk.TurnEnd,fk.TurnStart,fk.BuryVictim,fk.Damage},
  can_refresh = function (self, event, target, player, data)
    if event == fk.EventPhaseStart then
      return target == player and player:getMark("joy_lunce1") ~= 0 and player.phase == Player.Play
    elseif event == fk.TargetSpecified then
      if target == player and player:getMark("joy_lunce2") ~= 0 and player.room.current and player.room.current == player  and data.card.trueName == "slash" and data.firstTarget then
        local room = player.room
        local to = room:getPlayerById(data.to)
        if not to.dead  then
          local use_event = room.logic:getCurrentEvent():findParent(GameEvent.UseCard, true)
          if use_event == nil then return false end
          local x = player:getMark("joylunce2_" .. data.card.trueName.."-turn")
          if x == 0 then
            room.logic:getEventsOfScope(GameEvent.UseCard, 1, function (e)
              local use = e.data[1]
              if use.from == player.id and use.card.trueName == data.card.trueName then
                x = e.id
                room:setPlayerMark(player, "joylunce2_" .. data.card.trueName.."-turn", x)
                return true
              end
            end, Player.HistoryTurn)
          end
          return x == use_event.id
        end
      end
    elseif event == fk.TurnEnd then
      return target == player and (player:getMark("joy_lunce1") ~= 0 or player:getMark("joy_lunce2") ~= 0 or player:getMark("joy_lunce3") ~= 0)
    elseif event == fk.TurnStart then
      return target == player
    elseif event == fk.BuryVictim then
      return target == player
    elseif event == fk.Damage then
      return target == player and player:getMark("joy_lunce3") ~= 0 and player.phase == Player.Play and data.card and data.card.trueName == "slash"
    end
  end,
  on_refresh = function (self, event, target, player, data)
    local room = player.room
    if event == fk.EventPhaseStart then
      local tar = room:getPlayerById(player:getMark("joy_lunce1"))
      room:notifySkillInvoked(tar,"上策","offensive")
      tar:broadcastSkillInvoke(self.name)
      room:doIndicate(tar.id,{player.id})
      local use = room:askForUseCard(player,"slash","slash","上策：你可以使用一张无距离、次数限制的【杀】",true,{bypass_times = true,bypass_distances = true})
      if use then
        use.extraUse = true
        room:addPlayerMark(tar,"@joy_lanhai-round",1)
        room:setPlayerMark(player,"joy_lunce1_vic-turn",1)
        room:setBanner("joy_lunce_vic",1)
        room:useCard(use)
      end
    elseif event == fk.TargetSpecified then
      local tar = room:getPlayerById(player:getMark("joy_lunce2"))
      room:notifySkillInvoked(tar,"中策","control")
      tar:broadcastSkillInvoke(self.name)
      room:addPlayerMark(tar,"@joy_lanhai-round",1)
      room:setPlayerMark(player,"joy_lunce2_vic-turn",1)
      room:setBanner("joy_lunce_vic",1)
      if not player:isNude() then
        local cards = room:askForCardsChosen(tar,player,1,1,"he",self.name,"中策：选择 %src 的一张牌获得:"..player.id)
        if #cards > 0 then
          room:obtainCard(tar,cards,false,fk.ReasonPrey,tar.id,self.name)
        end
      end
    elseif event == fk.TurnEnd then
      if target:getMark("joy_lunce3") ~= 0 and target:getMark("joy_lunce3_novic-turn") == 0 then
          local tar = room:getPlayerById(player:getMark("joy_lunce3"))
          room:notifySkillInvoked(tar,"下策","support")
          tar:broadcastSkillInvoke(self.name)
          room:addPlayerMark(tar,"@joy_lanhai-round",1)
          room:setPlayerMark(player,"joy_lunce3_vic-turn",1)
          room:setBanner("joy_lunce_vic",1)
          if not player.dead then
            local cards = room:askForCard(tar,1,3,true,self.name,true,".","下策：你可将至多3张牌交给 %src 并令其回复1点体力:"..player.id)
            if #cards > 0 then
              room:obtainCard(player,cards,false,fk.ReasonGive,tar.id,self.name)
              if not player.dead and player:isWounded() then
                room:recover { num = 1, skillName = self.name, who = player, recoverBy = tar}
              end
            end
          end
      end
      for _, ce in ipairs({"joy_lunce1","joy_lunce2","joy_lunce3"}) do
        if player:getMark(ce) ~= 0 then
          if player:getMark(ce.."_vic-turn") == 0 then
            room:setBanner("joy_lunce_novic",1)
          end
        end
        room:setPlayerMark(player,ce,0)
        room:setPlayerMark(player,"@@"..ce,0)
      end
      room:setBanner("joy_lunce-turn",1)
    elseif event == fk.TurnStart then
      room:setBanner("joy_lunce-turn",0)
      room:setBanner("joy_lunce_vic",0)
      room:setBanner("joy_lunce_novic",0)
      if (player:getMark("joy_lunce1") ~= 0 or player:getMark("joy_lunce2") ~= 0 or player:getMark("joy_lunce3") ~= 0) then
        room:setBanner("joy_lunce-turn",1)
      end
    elseif event == fk.BuryVictim then
      for _, ce in ipairs({"joy_lunce1","joy_lunce2","joy_lunce3"}) do
          if player:getMark(ce.."_vic-turn")  ~= 0 then
            room:setBanner("joy_lunce_novic",1)
          end
      end
      for _, p in ipairs(room.alive_players) do
        for _, ce in ipairs({"joy_lunce1","joy_lunce2","joy_lunce3"}) do
          if p:getMark(ce) == player.id then
            if p:getMark(ce.."_vic-turn") == 0 then
              room:setBanner("joy_lunce_novic",1)
            end
          end
        end
      end
    elseif event == fk.Damage then
      room:setPlayerMark(player,"joy_lunce3_novic-turn",1)
    end
  end,
}
local lanhai = fk.CreateTriggerSkill{
  name = "joy__lanhai",
  anim_type = "drawcard",
  events = {fk.TurnEnd},
  frequency = Skill.Compulsory,
  can_trigger = function(self, event, target, player, data)
    return player:hasSkill(self) and player.room:getBanner("joy_lunce-turn") and player.room:getBanner("joy_lunce-turn") == 1
  end,
  on_cost = function(self, event, target, player, data)
    return true
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    local a,b = false,false
    if player.room:getBanner("joy_lunce_vic") and player.room:getBanner("joy_lunce_vic") == 1 then
      a = true
    end
    if player.room:getBanner("joy_lunce_novic") and player.room:getBanner("joy_lunce_novic") == 1 then
      b = true
    end
    if a then
      if player:getMark("@joy_lanhai-round") > 0 then
        player:drawCards(math.min(3,player:getMark("@joy_lanhai-round")),self.name)
      end
      if not player.dead then
        player.room.logic:trigger("fk.joy_lanhai", player)
      end
    end
    if player.dead then return end
    if b then
      if player:getMark(self.name) < 3 then
        room:addPlayerMark(player,self.name,1)
        room:changeMaxHp(player,1)
      end
      if not player.dead and player:isWounded() then
        room:recover { num = 1, skillName = self.name, who = player, recoverBy = player}
      end
    end
  end,
}
local pangtong = General(extension, "joy__godpangtong", "god",3)
pangtong:addSkill(lunce)
pangtong:addSkill(lanhai)
Fk:loadTranslationTable{
  ["joy__godpangtong"] = "神庞统",
  ["joy__lunce"] = "论策",
  [":joy__lunce"] = "每轮开始时，你可以选择一项并指定场上一名角色："..
  "<br>①上策，其出牌阶段开始时可立即使用一张【杀】（无距离和次数限制）;"..
  "<br>②中策，直到其回合结束，其回合内首次使用【杀】指定目标时，你获得其一张牌；"..
  "<br>③下策，其回合结束时，若其本回合出牌阶段未使用【杀】造成过伤害，你可将至多3张牌交给其并令其回复1点体力。",

  ["joy__lanhai"] = "览害",
  [":joy__lanhai"] = "锁定技，当有计策的角色回合结束时，若本回合有计策："..
  "<br>①成功发动，你摸X张牌并发动一次“论策”；（X为你本轮计策成功的次数，至多为3）"..
  "<br>②未成功发动，你增加1点体力和体力上限。（体力上限至多以此法增加3点）",
  ["@joy_lanhai-round"] = "论策",
  ["@@joy_lunce1"] = "上策",
  ["joy_lunce1"] = "上策",
  [":joy_lunce1"] = "其出牌阶段开始时可立即使用一张【杀】（无距离和次数限制）",
  ["@@joy_lunce2"] = "中策",
  ["joy_lunce2"] = "中策",
  [":joy_lunce2"] = "直到其回合结束，其回合内首次使用【杀】指定目标时，你获得其一张牌",
  ["@@joy_lunce3"] = "下策",
  ["joy_lunce3"] = "下策",
  [":joy_lunce3"] = "其回合结束时，若其本回合出牌阶段未使用【杀】造成过伤害，你可将至多3张牌交给其并令其回复1点体力",
  ["$joy__lunce1"] = "此计若成，西川可定！",
  ["$joy__lunce2"] = "某有三策，请主公自择而行。",
  ["$joy__lanhai1"] = "览倚仗之要害，吾似有一日之长。",
  ["$joy__lanhai2"] = "有的放矢，计出万全。",
  ["~joy__godpangtong"] = "臣以不决，以致大患。",
}

return extension